SpringBoot 配置 跨域支持


👆關注微信公眾號,獲取更多編程內容


跨域資源共享(CORS,請求協議,請求地址,請求端口三者必須相同才是同一服務器,否則都要進行跨域操作)標准新增了一組 HTTP 首部字段,允許服務器聲明哪些源站有權限訪問哪些資源。另外,規范要求,對那些可能對服務器數據產生副作用的 HTTP 請求方法(特別是 GET 以外的 HTTP 請求,或者搭配某些 MIME 類型的 POST 請求),瀏覽器必須首先使用 OPTIONS 方法發起一個預檢請求(preflight request),從而獲知服務端是否允許該跨域請求。服務器確認允許之后,才發起實際的 HTTP 請求。在預檢請求的返回中,服務器端也可以通知客戶端,是否需要攜帶身份憑證(包括 Cookies 和 HTTP 認證相關數據)。

常見的CORS的HTTP頭

其根本是在請求響應結果中添加響應頭,來表名服務支持CORS,因此常見的CORS頭如下:

名稱 示例 作用
Access-Control-Allow-Origin https://www.zhoutao123.com 表明它允許"www.zhoutao123.com"發起跨域請求
Access-Control-Max-Age 3628800 表明在3628800秒內,不需要再發送預檢驗請求
Access-Control-Allow-Methods GET,PUT, DELETE 允許GET、PUT、DELETE的外域請求
Access-Control-Allow-Headers content-type 允許跨域請求包含content-type頭

CORS執行流程

CORS在首次請求跨域服務器之前,都要進行預檢請求 ,會首先發送一個OPTIONS請求檢查是否支持CORS,待服務器響應之后,在進行后續的操作,具體流程圖下,當然並不是每個請求都會發送OPTIONS請求,在確認支持CORS之后,瀏覽器會把驗證結果緩存下來,緩存的有效時間可以通過 Access-Control-Max-Age 來控制:

![](https://www.zhoutao123.com/wp-content/uploads/2018/06/prelight-283x300.png)

預檢請求重定向

大多數瀏覽器不支持針對於預檢請求的重定向。如果一個預檢請求發生了重定向,瀏覽器將報告錯誤:

The request was redirected to 'https://example.com/foo', which is disallowed for cross-origin requests that require preflight

Request requires preflight, which is disallowed to follow cross-origin redirect

CORS 最初要求該行為,不過在后續的修訂中廢棄了這一要求。不過我們還是盡量不要對OPTIONS預檢請求做重定向處理.

  • 注意:因為CORS在發送真正的請求之前會發送OPTIONS請求,以此來驗證服務器是否支持跨域,此次預檢請求不攜帶任何真正請求的參數,當前也不包括我們設定的token參數,因此如果你的Spring應用或者其他應用在攔截器上做了驗證,請注意不要攔截OPTIONS請求,否則CORS支持會開啟失敗.

SpringBoot開啟CORS

非全局配置

So that the RESTful web service will include CORS access control headers in its response, you just have to add a @CrossOrigin annotation to the handler method

@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CrossOrigin {
	
	//允許跨域的服務器
	@AliasFor("origins")
	String[] value() default {};
	
	//和上面是一樣的 AliasFor
	@AliasFor("value")
	String[] origins() default {};

	//允許頭部
	String[] allowedHeaders() default {};

	String[] exposedHeaders() default {};
	
	/**
	 * The list of supported HTTP request methods.
	 * <p>By default the supported methods are the same as the ones to which a
	 * controller method is mapped.
	 */
	RequestMethod[] methods() default {};
	
	String allowCredentials() default "";
	
	/**
	 * The maximum age (in seconds) of the cache duration for preflight responses.
	 * <p>This property controls the value of the {@code Access-Control-Max-Age}
	 * response header of preflight requests.
	 * <p>Setting this to a reasonable value can reduce the number of preflight
	 * request/response interactions required by the browser.
	 * A negative value means <em>undefined</em>.
	 * <p>By default this is set to {@code 1800} seconds (30 minutes).
	 */
	long maxAge() default -1;
}

只要在SpringBoot的Mapper()接口中添加並配置此注解即可

	//根據CrossOrigin的注釋可以再請求參數的不存在的時候,CORS支持的方法和Mapper支持的方法一致
    @CrossOrigin(origins = "http://localhost:9000")
    @GetMapping("/test")
    public Greeting greeting(@RequestParam(required=false, defaultValue="World") String name) {
        System.out.println("==== in tesing ====");
        return "SUCCESS";
    }

全局配置

在大量接口需要開啟CORS支持的時候,上面的方式顯然不適合操作,因此Spring提供了全局配置CORS支持的方式。

  @Bean
  @SuppressWarnings("deprecation")
  public WebMvcConfigurer corsConfigurer() {
    return new WebMvcConfigurerAdapter() {
      @Override
      public void addCorsMappings(CorsRegistry registry) {
        log.info("CORS 配置參數 origins = {}  url = {}", allowedOrigins, allowedUrl);
        registry
            .addMapping("/**")
            .allowedMethods("GET", "POST", "PATCH", "DELETE", "PUT", "OPTIONS")
            .allowedOrigins("http://localhost:9090");
      }
    };
  }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM