偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

徹底搞懂跨域問題SpringBoot助你暢通無阻

網(wǎng)絡(luò) 網(wǎng)絡(luò)管理
出于安全性,瀏覽器限制腳本內(nèi)發(fā)起的跨源 HTTP 請求。例如,XMLHttpRequest 和 Fetch API 遵循同源策略。這意味著使用這些 API 的 Web 應(yīng)用程序只能從加載應(yīng)用程序的同一個域請求 HTTP 資源,除非響應(yīng)報文包含了正確 CORS 響應(yīng)頭。

環(huán)境:SpringBoot2.7.16

1. 簡介

跨源資源共享(CORS,或通俗地譯為跨域資源共享)是一種基于 HTTP 頭的機(jī)制,該機(jī)制通過允許服務(wù)器標(biāo)示除了它自己以外的其他源(域、協(xié)議或端口),使得瀏覽器允許這些源訪問加載自己的資源??缭促Y源共享還通過一種機(jī)制來檢查服務(wù)器是否會允許要發(fā)送的真實請求,該機(jī)制通過瀏覽器發(fā)起一個到服務(wù)器托管的跨源資源的“預(yù)檢”請求。在預(yù)檢中,瀏覽器發(fā)送的頭中標(biāo)示有 HTTP 方法和真實請求中會用到的頭。

跨源 HTTP 請求例子:運(yùn)行在https://www.a.com 的 JavaScript 代碼使用 XMLHttpRequest 來發(fā)起一個到 https://www.b.com/data.json 的請求。

出于安全性,瀏覽器限制腳本內(nèi)發(fā)起的跨源 HTTP 請求。例如,XMLHttpRequest 和 Fetch API 遵循同源策略。這意味著使用這些 API 的 Web 應(yīng)用程序只能從加載應(yīng)用程序的同一個域請求 HTTP 資源,除非響應(yīng)報文包含了正確 CORS 響應(yīng)頭。

圖片圖片

什么情況下需要 CORS?

這份跨源共享標(biāo)準(zhǔn)允許在下列場景中使用跨站點(diǎn) HTTP 請求:

  •  XMLHttpRequest 或 Fetch API 發(fā)起的跨源 HTTP 請求。
  • Web 字體(CSS 中通過 @font-face 使用跨源字體資源),因此,網(wǎng)站就可以發(fā)布 TrueType 字體資源,并只允許已授權(quán)網(wǎng)站進(jìn)行跨站調(diào)用。
  • WebGL 貼圖。
  • 使用 drawImage() 將圖片或視頻畫面繪制到 canvas。
  • 來自圖像的 CSS 圖形 (en-US)。

跨源資源共享標(biāo)準(zhǔn)新增了一組 HTTP 標(biāo)頭字段,允許服務(wù)器聲明哪些源站通過瀏覽器有權(quán)限訪問哪些資源。另外,規(guī)范要求,對那些可能對服務(wù)器數(shù)據(jù)產(chǎn)生副作用的 HTTP 請求方法(特別是 GET 以外的 HTTP 請求,或者搭配某些 MIME 類型的 POST 請求),瀏覽器必須首先使用 OPTIONS 方法發(fā)起一個預(yù)檢請求(preflight request),從而獲知服務(wù)端是否允許該跨源請求。服務(wù)器確認(rèn)允許之后,才發(fā)起實際的 HTTP 請求。在預(yù)檢請求的返回中,服務(wù)器端也可以通知客戶端,是否需要攜帶身份憑證(例如 Cookie 和 HTTP 認(rèn)證相關(guān)數(shù)據(jù))。

CORS 請求失敗會產(chǎn)生錯誤,但是為了安全,在 JavaScript 代碼層面無法獲知到底具體是哪里出了問題。你只能查看瀏覽器的控制臺以得知具體是哪里出現(xiàn)了錯誤。

什么是預(yù)檢請求?

一個 CORS 預(yù)檢請求是用于檢查服務(wù)器是否支持 CORS 即跨域資源共享。它一般是用了以下幾個 HTTP 請求首部的 OPTIONS 請求:Access-Control-Request-Method 和 Access-Control-Request-Headers,以及一個 Origin 首部。當(dāng)有必要的時候,瀏覽器會自動發(fā)出一個預(yù)檢請求;所以在正常情況下,前端開發(fā)者不需要自己去發(fā)這樣的請求。

舉個例子,一個客戶端可能會在實際發(fā)送一個 DELETE 請求之前,先向服務(wù)器發(fā)起一個預(yù)檢請求,用于詢問是否可以向服務(wù)器發(fā)起一個 DELETE 請求:

OPTIONS /resource/foo
Access-Control-Request-Method: DELETE
Access-Control-Request-Headers: origin, x-requested-with
Origin: https://foo.bar.org

如果服務(wù)器允許,那么服務(wù)器就會響應(yīng)這個預(yù)檢請求。并且其響應(yīng)頭 Access-Control-Allow-Methods 會將 DELETE 包含在其中:

HTTP/1.1 200 OK
Content-Length: 0
Connection: keep-alive
Access-Control-Allow-Origin: https://foo.bar.org
Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE
Access-Control-Max-Age: 86400

針對CORS的HTTP Headers:

  • Access-Control-Allow-Origin指示響應(yīng)的資源是否可以被給定的來源共享。
  • Access-Control-Allow-Credentials指示當(dāng)請求的憑證標(biāo)記為 true 時,是否可以公開對該請求響應(yīng)。
  • Access-Control-Allow-Headers用在對預(yù)檢請求的響應(yīng)中,指示實際的請求中可以使用哪些 HTTP 標(biāo)頭。
  • Access-Control-Allow-Methods指定對預(yù)檢請求的響應(yīng)中,哪些 HTTP 方法允許訪問請求的資源。
  • Access-Control-Expose-Headers通過列出標(biāo)頭的名稱,指示哪些標(biāo)頭可以作為響應(yīng)的一部分公開。
  • Access-Control-Max-Age指示預(yù)檢請求的結(jié)果能被緩存多久。
  • Access-Control-Request-Headers用于發(fā)起一個預(yù)檢請求,告知服務(wù)器正式請求會使用哪些 HTTP 標(biāo)頭。
  • Access-Control-Request-Method用于發(fā)起一個預(yù)檢請求,告知服務(wù)器正式請求會使用哪一種 HTTP 請求方法。
  • Origin指示獲取資源的請求是從什么源發(fā)起的。
  • Timing-Allow-Origin指定特定的源,以允許其訪問 Resource Timing API 功能提供的屬性值,否則由于跨源限制,這些值將被報告為零。

大致了解了CORS后,接下來介紹在SpringBoot中如何解決跨域問題

2. 實戰(zhàn)案例

Spring MVC HandlerMapping實現(xiàn)提供了對CORS的內(nèi)置支持。在成功地將請求映射到處理程序之后,HandlerMapping實現(xiàn)檢查給定請求和處理程序的CORS配置,并采取進(jìn)一步的操作。Preflight requests(預(yù)檢請求)被直接處理,而簡單和實際的CORS請求被攔截、驗證,并設(shè)置了所需的CORS響應(yīng)頭。

2.1 @CrossOrigin

@CrossOrigin注釋允許對帶注釋的控制器方法進(jìn)行跨域請求,如下例所示:

@RestController
@RequestMapping("/accounts")
public class AccountController {


  @CrossOrigin
  @GetMapping("/{id}")
  public Account retrieve(@PathVariable Long id) {
    // ...
  }
  @DeleteMapping("/{id}")
  public void remove(@PathVariable Long id) {
    // ...
  }
}

默認(rèn)情況下,@CrossOrigin允許:

  • 所有請求來源origins。
  • 所有請求headers。
  • 控制器方法映射到的所有HTTP方法。

注意:默認(rèn)情況下不啟用allowCredentials,因為它建立了一個公開敏感的用戶特定信息(如Cookie和CSRF令牌)的信任級別,并且只應(yīng)在適當(dāng)?shù)牡胤绞褂?。啟用時,必須將allowOrigins設(shè)置為一個或多個特定域(但不是特殊值“*”),或者可以使用allowOringPatterns屬性來匹配一組動態(tài)原點(diǎn)。

maxAge 默認(rèn)30分鐘。

@CrossOrigin在類級別也受支持,并由所有方法繼承,如下例所示:

@CrossOrigin(origins = "https://www.pack.com", maxAge = 3600)
@RestController
@RequestMapping("/accounts")
public class AccountController {


  @GetMapping("/{id}")
  public Account retrieve(@PathVariable Long id) {
    // ...
  }
}

你可以在類級別和方法級別使用@CrossOrigin,如下例所示:

@CrossOrigin(maxAge = 3600)
@RestController
@RequestMapping("/accounts")
public class AccountController {


  @CrossOrigin("http://www.pack.com")
  @GetMapping("/{id}")
  public Account retrieve(@PathVariable Long id) {
    // ...
  }
}

2.2 全局配置

除了細(xì)粒度的控制器方法級配置外,你還可以全局CORS配置??梢栽谌魏蜨andlerMapping上單獨(dú)設(shè)置基于URL的CorsConfiguration映射。

默認(rèn)情況下,全局配置啟用以下功能:

  • 所有請求來源origins.
  • 所有請求headers.
  • GET, HEAD, and POST methods.
@Configuration
public class WebConfig implements WebMvcConfigurer {


  @Override
  public void addCorsMappings(CorsRegistry registry) {
    registry.addMapping("/api/**")
      .allowedOrigins("http://www.pack.com")
      .allowedMethods("PUT", "DELETE")
      .allowedHeaders("header1", "header2", "header3")
      .exposedHeaders("header1", "header2")
      .allowCredentials(true).maxAge(3600) ;
  }
}

2.3 CORS過濾器

可以通過內(nèi)置的CorsFilter應(yīng)用CORS支持。

注意:如果你嘗試將CorsFilter與Spring Security一起使用,請記住Spring Security內(nèi)置了對CORS的支持。

要配置篩選器,請將CorsConfigurationSource傳遞給其構(gòu)造函數(shù),如下例所示:

@Bean
public CorsFilter corsFilter() {
  CorsConfiguration config = new CorsConfiguration() ;
  config.setAllowCredentials(true) ;
  config.addAllowedOrigin("http://www.pack.com") ;
  config.addAllowedHeader("*") ;
  config.addAllowedMethod("*") ;
  UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource() ;
  source.registerCorsConfiguration("/**", config) ;
  CorsFilter filter = new CorsFilter(source) ;
  return filter ;
}

當(dāng)然你也可以使用自定義的Filter來解決CORS問題。

@WebFilter("/*")
public class WebCORSFilter implements Filter {


  public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
      throws IOException, ServletException {
    HttpServletResponse response = (HttpServletResponse) res ;
    HttpServletRequest request = (HttpServletRequest) req ;
    String origin = request.getHeader("Origin") ;
    request.setCharacterEncoding("UTF-8") ;
    response.setHeader("Access-Control-Allow-Origin", origin) ;
    response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT") ;
    response.setHeader("Access-Control-Max-Age", "3600");
    response.setHeader("Access-Control-Allow-Credentials", "true") ;
    response.setHeader("Access-Control-Allow-Headers",
        "Origin, X-Requested-With, Content-Type, Accept, Account, access-token") ;
    chain.doFilter(req, res) ;
  }
}

以上是本篇文章的全部內(nèi)容,希望對你有幫助。

責(zé)任編輯:武曉燕 來源: Springboot實戰(zhàn)案例錦集
相關(guān)推薦

2009-01-07 09:18:00

2010-01-22 17:24:39

交換機(jī)和路由器

2010-04-14 14:53:31

優(yōu)化無線交換機(jī)

2013-08-02 10:35:24

2018-09-19 14:50:05

2011-06-03 12:34:33

噴墨打印機(jī)技巧

2011-04-28 10:34:06

傳真機(jī)

2024-10-29 16:41:24

SpringBoot跨域Java

2022-04-24 11:06:54

SpringBootjar代碼

2023-05-19 16:44:48

銳捷

2024-12-02 14:30:20

2022-08-27 13:35:39

L4級自動駕駛輔助駕駛自動駕駛

2025-04-21 04:00:00

2020-08-13 07:04:45

跨域CORS瀏覽器

2017-08-20 12:49:59

瀏覽器跨域服務(wù)器

2022-04-11 10:56:43

線程安全

2024-01-03 13:39:00

JS,Javascrip算法

2023-10-18 10:55:55

HashMap

2025-04-11 05:55:00

2025-01-13 16:00:00

服務(wù)網(wǎng)關(guān)分布式系統(tǒng)架構(gòu)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號