最近作了一個先後端分離的web項目,其中我司職後端,使用django框架。在先後端集成測試的時候,就遇到了一些web安全相關的問題,cors跨域資源共享就是其中之一。前端
跨域資源共享(CORS) 是一種機制,它使用額外的 HTTP 頭來告訴瀏覽器 讓運行在一個 origin (domain) 上的Web應用被准許訪問來自不一樣源服務器上的指定的資源。當一個資源從與該資源自己所在的服務器不一樣的域、協議或端口請求一個資源時,資源會發起一個跨域 HTTP 請求。 CORS機制容許 Web 應用服務器進行跨域訪問控制,從而使跨域數據傳輸得以安全進行。現代瀏覽器支持在API容器中使用CORS,以下降跨域 HTTP 請求所帶來的風險。web
一個域是由協議、主機和端口號組成的,簡單地說,當兩個url的協議、主機和端口中存在一個不一樣時,它們屬於不一樣域,那麼它們之間的互相訪問就會產生跨域訪問問題。django
個人項目中,前端的地址是http://localhost:8001
,後端的地址是http://localhost:8000
,兩個地址的協議和主機都相同,可是端口號不一樣,所以,前端調用後端接口時,就會產生跨域訪問的問題。後端
簡單請求不會觸發跨域訪問中的預檢請求,知足下列條件的爲簡單請求:跨域
GET
HEAD
POST
Accept
Accept-Language
Content-Language
Content-type
:text/plain
、multipart/form-data
和application/x-www-form-urlencoded
DRP
DownLink
Save-Data
Viewport-Width
Width
非簡單請求即不知足簡單請求條件的請求。非簡單請求在發出請求前須要先發送一個預檢請求,請求方法爲OPTIONS
方法。預檢請求的使用,能夠避免跨域請求對服務器的用戶數據產生未預期的影響。 當請求知足下述任一條件時,即應首先發送預檢請求:瀏覽器
PUT
DELETE
CONNECT
OPTIONS
TRACE
PATCH
在後臺開發中,就遇到了這樣的狀況緩存
錯誤提示中顯示,請求被CORS
協議阻攔。安全
Origin
字段說明了請求源地址,採用了
OPTIONS
方法,而後發出請求的地址
Host
就是本機地址。下面是服務器的響應,可是沒有發出實際請求
CORS
安全的首部字段集合以外的字段,因此,向服務器發送一個預檢請求。上圖可見,方法爲OPTIONS
,該方法不會對服務器資源產生影響。其中的請求頭中的Access-Control-Request-Method
字段代表實際請求會採用GET
方法,Origin
表示請求源,會在服務器中接受驗證。response
請求頭添加不一樣的字段進行返回, 字段的意思以下:
Access-Control-Allow-Headers
:表示服務器容許的頭部字段。Access-Control-Allow-Methods
:代表服務器容許客戶端使用 POST
, GET
和 OPTIONS
等等方法發起請求。Access-Control-Allow-Origin
:表示服務器容許的請求源。Access-Control-Max-Age
:代表該響應的有效時間爲86400秒,也就是24 小時。在有效時間內,瀏覽器無須爲同一請求再次發起預檢請求。response
請求體中沒有任何信息,而實際請求則攜帶了服務器返回的信息。不難看出,預檢請求確實就是與服務器提早溝通,獲取與服務器相關信息的。非簡單請求須要發送預檢請求進行判斷,而後服務端與客戶端須要在頭部字段上達成一致,這樣才能正常訪問。不過,在django的開發中,直接使用django-cors-headers庫之後,只須要簡單的配置就可以很好的解決問題。服務器
我在測試時嘗試使用本身寫的中間件來補充頭部信息,可是在瀏覽器清除緩存後,就會致使登陸異常,而且瀏覽器沒有顯示預檢請求。等問題解決後,會把問題和解決方案再更新上來。app
若是有什麼不對之處歡迎指正!