狀況描述:前端
最近在部署一個先後端分離的項目出現了跨域問題*,spring
項目使用jwt進行鑑權,須要前端請求發起攜帶TOKEN的請求*,請求所帶的token沒法成功發送給後端,json
使用跨域後出現了兼容性問題:Chrome、Firefox瀏覽器正常,而IE仍是報跨域錯誤後端
1、跨域問題在項目中可使用CORS解決
方式一跨域
@CrossOrigin瀏覽器
在每一個controller類加上spring-mvc
方式二 直接在spring-mvc中加入配置服務器
<!-- 接口跨域配置 -->mvc
<mvc:cors>app
<mvc:mapping path="/**"
allowed-origins="*"
allowed-methods="POST, GET, OPTIONS, DELETE, PUT"
allowed-headers="Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With"
allow-credentials="true" />
</mvc:cors>
方式三 能夠在interceptor中向response增長header
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS");
response.setHeader("Access-Control-Max-Age", "86400");
response.setHeader("Access-Control-Allow-Headers", "Authorization,Overwrite, Destination, Content-Type, Depth, User-Agent, Translate, Range, Content-Range, Timeout, X-File-Size, X-Requested-With, If-Modified-Since, X-File-Name, Cache-Control, Location, Lock-Token, If");
上面三種方式對通常的簡單跨域請求有效,能夠知足大部分須要。但遇到非簡單跨域請求的狀況,就會出現問題,須要作一下調整。
2、複雜請求下須要對options預檢請求進行處理
先後端分離的項目中,瀏覽器請求中常常會出現非簡單跨域請求,這將會發送請求2次,第一條由瀏覽器發起請求爲options的預檢請求,再根據服務器的返回內容由瀏覽器判斷服務器是否容許這次請求,第二條纔是method中的get,post或者put等,而且第一條無任何數據返回,第二條才正常返回數據。
因此咱們會遇到:咱們處理token的攔截器(非簡單狀況,在header的authorization攜帶了token進行鑑權),在接收到option的時候將這個預檢請求當成正常的請求,而options請求時沒法在header攜帶token的,所以後端將會把第一個請求打回,致使第二個請求沒法正常發起。
非簡單狀況(含如下之一):
- 請求方式:PUT、DELETE
- 自定義頭部字段
- 發送json格式數據
- 正式通訊以前,瀏覽器會先發送OPTION請求,進行預檢,這一次的請求稱爲「預檢請求」
- 服務器成功響應預檢請求後,纔會發送真正的請求,而且攜帶真實數據
解決方式 在後端中對options請求進行直接給經過(只要返回200、204,瀏覽器即判斷服務器容許請求)
增長一個CorsInterceptor
public class CorsInterceptor implements HandlerInterceptor { //使用了方式3、進行CORS配置 response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Allow-Credentials", "true"); response.setHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS"); response.setHeader("Access-Control-Max-Age", "86400"); response.setHeader("Access-Control-Allow-Headers", "Authorization,Overwrite, Destination, Content-Type, Depth, User-Agent, Translate, Range, Content-Range, Timeout, X-File-Size, X-Requested-With, If-Modified-Since, X-File-Name, Cache-Control, Location, Lock-Token, If"); if(HttpMethod.OPTIONS.toString().equals(httpServletRequest.getMethod())){ response.setStatus(HttpStatus.NO_CONTENT.value()); System.out.println("是options請求、跳過"); return false; } return true; } }
在spring-mvc中加載這個CorsInterceptor,置於token處理以前
<mvc:interceptor> <mvc:mapping path="/**" /> <bean class="cn.gdyvc.interceptor.CorsInterceptor" /> </mvc:interceptor>
3、CORS瀏覽器兼容問題
最後部署完成,可是Chrome、Firefox瀏覽器正常,而IE仍是報跨域錯誤,遇到了Internet Explorer與Access-Control-Allow-Methods的CORS問題
剛開始跨域配置根據網上的的設置將Access-Control-Allow-Headers對應設置爲「*」,而Ie的是不可以響應*的,須要將header的各列單獨列出來
參考連接:
https://www.jianshu.com/p/5c637bfcc674
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers