天天看點

ajax通路不到webmethod_SpringBoot 實作前後端分離的跨域通路(CORS)一、基本介紹1. CORS工作原理2. Request Headers(請求頭)3. Response headers(響應頭 )二、CORS實作跨域通路授權方式1. 傳回新的CorsFilter(全局跨域)

作者:yizhiwazi

連結:https://www.jianshu.com/p/477e7eaa6c2f

序言:跨域資源共享向來都是熱門的需求,使用CORS可以幫助我們快速實作跨域通路,隻需在服務端進行授權即可,無需在前端添加額外設定,比傳統的JSONP跨域更安全和便捷。

一、基本介紹

簡單來說,CORS是一種通路機制,英文全稱是Cross-Origin Resource Sharing,即我們常說的跨域資源共享,通過在伺服器端設定響應頭,把發起跨域的原始域名添加到Access-Control-Allow-Origin 即可。

1. CORS工作原理

CORS實作跨域通路并不是一蹴而就的,需要借助浏覽器的支援,從原理題圖我們可以清楚看到,簡單的請求(通常指GET/POST/HEAD方式,并沒有去增加額外的請求頭資訊)直接建立了跨域請求的XHR對象,而複雜的請求則要求先發送一個"預檢"請求,待伺服器準許後才能真正發起跨域通路請求。

ajax通路不到webmethod_SpringBoot 實作前後端分離的跨域通路(CORS)一、基本介紹1. CORS工作原理2. Request Headers(請求頭)3. Response headers(響應頭 )二、CORS實作跨域通路授權方式1. 傳回新的CorsFilter(全局跨域)

根據官方文檔W3C規範的描述,目前CORS使用了如下頭部資訊:

2. Request Headers(請求頭)

溫馨提示:Request Headers 無需人為幹預,因為浏覽器會自動識别跨域請求并添加對應的請求頭。
  • Origin 表示發起跨域請求的原始域。
  • Access-Control-Request-Method 表示發起跨域請求的方式,例如GET/POST。
  • Access-Control-Request-Headers表示發起跨域請求的額外頭資訊。

3. Response headers(響應頭 )

溫馨提示:Response Headers 需要人為幹預,通過設定響應頭以幫助伺服器資源進行跨域授權,例如允許哪些原始域進行跨域請求,是否允許響應資訊攜帶Cookie等認證資訊。
  • Access-Control-Allow-Origin 表示允許哪些原始域進行跨域通路。
  • Access-Control-Allow-Credentials表示是否允許用戶端擷取使用者憑據。 使用場景:例如現在需要登入系統後才能發起跨域請求,并且要附帶Cookie資訊給伺服器。則必須具備兩個條件:1. 浏覽器端:發送AJAX請求前需設定通信對象XHR的withCredentials 屬性為true。 2.伺服器端:設定Access-Control-Allow-Credentials為true。兩個條件缺一不可,否則即使伺服器同意發送Cookie,浏覽器也無法擷取。正确姿勢如下:
$.ajax({ url: 'localhost:8080', xhrFields: { withCredentials: true //表示發起跨域通路并要求攜帶Cookie等認證資訊 }, success: function (r) { console.log(r) }});
           

有好奇的小夥伴可能會問為什麼在W3C手冊中找不到跨域屬性xhrFields的描述,因為該屬性并不是通信對象XHR的預設屬性,而是自定義屬性。

// Cross domain only allowed if supported through XMLHttpRequest if ( support.cors || xhrSupported && !options.crossDomain ) { return { send: function( headers, complete ) { var i, xhr = options.xhr(); xhr.open( options.type, options.url, options.async, options.username, options.password ); // Apply custom fields if provided if ( options.xhrFields ) { for ( i in options.xhrFields ) { xhr[ i ] = options.xhrFields[ i ]; } } ... }
           

Access-Control-Allow-Methods 表示允許哪些跨域請求的送出方式。(例如GET/POST)Access-Control-Allow-Headers 表示跨域請求的頭部的允許範圍。Access-Control-Expose-Headers 表示允許暴露哪些頭部資訊給用戶端。 使用說明:基于安全考慮,如果沒有設定額外的暴露,跨域的通信對象XMLHttpRequest隻能擷取标準的頭部資訊。Access-Control-Max-Age 表示預檢請求的最大緩存時間

二、CORS實作跨域通路

授權方式

  • 方式1:傳回新的CorsFilter
  • 方式2:重寫WebMvcConfigurer
  • 方式3:使用注解(@CrossOrigin)
  • 方式4:手工設定響應頭(HttpServletResponse )
注:CorsFilter / WebMvcConfigurer / @CrossOrigin 需要SpringMVC 4.2 以上的版本才支援,對應SpringBoot 1.3 版本以上都支援這些CORS特性。不過,使用SpringMVC4.2 以下版本的小夥伴也不用慌,直接使用方式4通過手工添加響應頭來授權CORS跨域通路也是可以的。附:在SpringBoot 1.2.8 + SpringMVC 4.1.9 親測成功。
注:方式1和方式2屬于全局CORS配置,方式3和方式4屬于局部CORS配置。如果使用了局部跨域是會覆寫全局跨域的規則,是以可以通過@CrossOrigin注解來進行細粒度更高的跨域資源控制。

1. 傳回新的CorsFilter(全局跨域)

在任意配置類,傳回一個新的CorsFilter Bean,并添加映射路徑和具體的CORS配置資訊。

package com.hehe.yyweb.config;@Configurationpublic class GlobalCorsConfig { @Bean public CorsFilter corsFilter() { //1.添加CORS配置資訊 CorsConfiguration config = new CorsConfiguration(); //放行哪些原始域 config.addAllowedOrigin("*"); //是否發送Cookie資訊 config.setAllowCredentials(true); //放行哪些原始域(請求方式) config.addAllowedMethod("*"); //放行哪些原始域(頭部資訊) config.addAllowedHeader("*"); //暴露哪些頭部資訊(因為跨域通路預設不能擷取全部頭部資訊) config.addExposedHeader("*"); //2.添加映射路徑 UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource(); configSource.registerCorsConfiguration("/**
           

繼續閱讀