Tomcat默認不支持restful風格的put與delete請求、預檢請求相關的問題
Access to XMLHttpRequest at 'http://localhost:8080/employee/updateEmployee/' from origin 'http://localhost:63343' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
一般我們會自定義一個攔截器實現登錄攔截,使用spring mvc的CorsFilter過濾器解決跨域的問題,然而當你的請求滿足了攔截器時,請求繼續向下執行,沒有問題,但是當你的請求不滿足攔截器時,將會出現跨域問題,哪怕你解決了跨域問題都未必有效。
因為自定義的攔截器會在CorsFilter過濾器之前執行,因此會產生跨域問題
這時就可以使用自定義的Filter來解決跨域問題,因為過濾的是servlet的請求,我們的攔截器是spring mvc的攔截器,想要進入spring mvc的攔截器,前提是要進入spring mvc,進入springmvc 是通過dispatcherServler,滿足dispatcherServler中設置的請求才能進入,恰巧Filter可以對servlet進行攔截
然而在使用自定義Filter時,要注意兩點
1、Tomcat默認不支持restful風格的put與delete請求
這種情況下,我們可以選擇使用RequestMapping來接收請求,不使用put、delete;
或者用其他的方式解決(這裏我沒有仔細去看)
//TODO 標個todo回頭在寫
2、預檢請求的問題
概念
規範要求,對那些可能對服務器數據產生副作用的 HTTP 請求方法(特別是
GET以外的 HTTP 請求,或者搭配某些 MIME 類型的POST請求),瀏覽器必須首先使用OPTIONS方法發起一個預檢請求(preflight request),從而獲知服務端是否允許該跨域請求。服務器確認允許之後,才發起實際的 HTTP 請求。簡單請求不會觸發CORS預檢請求,而非簡單請求則會觸發。若請求滿足所有下述條件,則該請求可視為“簡單請求”,否則為非簡單請求:
- 使用下列方法之一:GET POST HEAD
- Fetch 規範定義了對 CORS 安全的首部字段集合,不得人為設置該集合之外的其他首部字段。該集合為:
AcceptAccept-LanguageContent-LanguageContent-Type()DPRDownlinkSave-DataViewport-WidthWidth
Content-Type的值僅限於下列三者之一:
text/plainmultipart/form-dataapplication/x-www-form-urlencoded
- 請求中的任意
XMLHttpRequestUpload對象均沒有註冊任何事件監聽器;XMLHttpRequestUpload對象可以使用XMLHttpRequest.upload屬性訪問。- 請求中沒有使用
ReadableStream對象。- 滿足上面所有的條件才不會發送預檢請求,在實際項目中我們的請求格式可能是
application/json格式編碼,或者使用自定義請求頭都會觸發CORS的預檢請求。也就是説瀏覽器會判斷是否是複雜請求,若是複雜請求,這時瀏覽器會先發送一個域請求向後台確認,若能請求成功,在發送真正的請求到後台,這裏需要注意的是,預檢請求是不攜帶session的,不僅是session還有很多信息都是不攜帶的,所以使用session存儲登錄信息做登錄攔截的,會遇到跨域問題。
解決方案:
一、幹掉預檢請求(不推薦)
在攔截器中放過預檢請求,這種方式是很不推薦的,就像我看的一篇博客説的,前輩們怕房子不安全,造了個門,而你沒有鑰匙,於是你便拆了門。
二、把請求轉換為簡單請求