自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

徹底搞懂跨域問(wèn)題SpringBoot助你暢通無(wú)阻

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

環(huán)境:SpringBoot2.7.16

1. 簡(jiǎn)介

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

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

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

圖片圖片

什么情況下需要 CORS?

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

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

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

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

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

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

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

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

如果服務(wù)器允許,那么服務(wù)器就會(huì)響應(yīng)這個(gè)預(yù)檢請(qǐng)求。并且其響應(yīng)頭 Access-Control-Allow-Methods 會(huì)將 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

針對(duì)CORS的HTTP Headers:

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

大致了解了CORS后,接下來(lái)介紹在SpringBoot中如何解決跨域問(wèn)題

2. 實(shí)戰(zhàn)案例

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

2.1 @CrossOrigin

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

@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允許:

  • 所有請(qǐng)求來(lái)源origins。
  • 所有請(qǐng)求headers。
  • 控制器方法映射到的所有HTTP方法。

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

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

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

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


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

你可以在類級(jí)別和方法級(jí)別使用@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ì)粒度的控制器方法級(jí)配置外,你還可以全局CORS配置??梢栽谌魏蜨andlerMapping上單獨(dú)設(shè)置基于URL的CorsConfiguration映射。

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

  • 所有請(qǐng)求來(lái)源origins.
  • 所有請(qǐng)求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過(guò)濾器

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

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

要配置篩選器,請(qǐng)將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來(lái)解決CORS問(wèn)題。

@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) ;
  }
}

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

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

2009-01-07 09:18:00

2010-01-22 17:24:39

交換機(jī)和路由器

2013-08-02 10:35:24

2010-04-14 14:53:31

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

2011-06-03 12:34:33

噴墨打印機(jī)技巧

2018-09-19 14:50:05

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級(jí)自動(dòng)駕駛輔助駕駛自動(dòng)駕駛

2020-08-13 07:04:45

跨域CORS瀏覽器

2025-04-21 04:00:00

2017-08-20 12:49:59

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

2022-04-11 10:56:43

線程安全

2021-06-06 13:05:15

前端跨域CORS

2024-08-28 08:45:22

2020-03-27 15:49:17

工業(yè)物聯(lián)網(wǎng)技術(shù)5G

2020-03-26 10:25:26

工業(yè)互聯(lián)網(wǎng)IT工業(yè)物聯(lián)網(wǎng)
點(diǎn)贊
收藏

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