原文地址html
當下不管大廠小廠的先後端開發模式都是先後端分離。之前遇到經過jsonp解決跨域的方式也漸漸的淡出的工程中(不瞭解jsonp的能夠看JSONP跨域請求+簡答實現百度搜索)。當前端請求一個接口的時候就會引發跨域,可是當下的前端構建工具都有相應的解決方案,好比webpack中web-dev-server這個插件,就能很簡單的啓一個本地的服務,而後發請求的時候經過啓的本地服務去發送請求,這樣就解決跨域問題的一部分了。這種狀況下客戶端代碼和正常非跨域請求一摸同樣,不用作任何改變。前端
上面說的方法只是解決了一部分,還有一部分我想你們可能或多或少的會遇到過,就是在登陸場景的時候。服務端的response裏面有set-cookie這個字段,在客戶端中設置cookie,cookie裏面可能包含着的seesionID表示的當前登陸的用戶/當前的登陸狀態(對這方面不理解的能夠看經過cookie和session讓http協議變得有狀態)。當用戶已經登陸而且訪問其餘頁面的時候,服務端會經過cookie中的信息去校驗用戶登陸狀態,若是請求中沒有攜帶身份信息或者身份信息過時(服務端返回401/403)就會跳轉到登陸界面。這種狀況若是在先後端聯調的時候比較麻煩,由於上面方法解決的跨域是不會攜帶cookie的。目前有兩種方法去解決這個:vue
綜上: CORS的主要任務都落在服務端,可是若是爲了聯調服務端的開發代碼和生產代碼有區別,他們確定是會不搞的。webpack
今天組裏的實習生在使用Axios去驗證登陸的時候遇到了跨域的問題(前端是vue, 後端是Spring boot)。 通常的請求經過前端設置代理,服務端設置Access-Control-Allow-origin:\*
就能夠了,可是登陸時候響應頭裏面要去set cookie就遇到了問題,結果因爲對CORS跨域理解的不是很深入,對預檢請求不是很瞭解,就在axios的issues裏面去搜,經過Axios doesn't send cookies with POST and data定位到了問題,原來他後端寫的攔截器裏面自動把OPTIONS這個請求給過濾掉了,沒有讓走到後面的流程。ios
CORS的出現是爲了解決因爲瀏覽器的同源策略帶來的請求跨域問題。git
「跨資源共享(Cross-Origin Resource Sharing(CORS))是經過HTTP Response header來告訴瀏覽器,讓運行在一個origin(domain)上的web應用被容許訪問來自不一樣源服務器上指定的資源的一種機制。」github
簡單來講: CORS就是經過設置請求的響應頭(能經過開發人員控制的基本都是服務端的響應頭,客戶端的也會有對應的請求頭,但通常不會是開發人員去控制的,後面會仔細說)去控制是否容許某個origin的某個/些請求跨域。web
CORS標準新增了一組HTTP首部字段,容許服務端聲明哪些源站經過瀏覽器有權訪問哪些資源。對於能對服務器產生反作用的HTTP非簡單請求(non-simple request)(特別是除了GET請求之外的請求),瀏覽器必須首先發送一個方法爲OPTIONS的一個預檢請求(preflight request)來獲取服務器是否容許該請求跨域。服務器獲得確認以後,才發起真正的HTTP請求。在預檢請求中,服務端也能夠通知客戶端是否要攜帶Credentials
.json
某些請求是不會觸發預檢查請求的,這些請求被成爲簡單請求(simple request)。 若是一個請求知足下列的全部條件就能夠被稱爲簡單請求:axios
application/x-www-form-urlencoded
multipart/form-data
text/plain
不知足上面定義的簡單請求,都會發送預檢請求。
好比瀏覽器要發送一個POST請求,content-Type爲application/json,新增一個request header爲X-TEST
預檢請求的步驟:
對於跨域(發生CORS)的請求默認是不會帶上憑證信息(credentials)的,若是要發送憑證信息(credentials)就須要設置對應的標識位。
請求:
響應:
HTTP規範規定Access-Control-Allow-Origin
不能是通配符*而且只能是單一的origin
。這是由於若是能設置多個的話,證實該服務器就能接受多個域名下面的cookie,這是很危險的。
Access-Control-Allow-Origin: <origin> | *
origin參數的值制定了容許訪問服務器資源的外域URI。對於不須要攜帶身份憑證的請求,服務器能夠指定這個字段的值爲通配符*,表示容許來自全部域的請求。
該頭信息服務器把容許瀏覽器訪問的頭放入白名單,例如:
Access-Control-Expose-Headers: X-My-Custom-Header, X-Another-Custom-Header
在跨域訪問的時候,XHR對象的getResponseHeader()只能拿到一些最基本的響應頭。
指定了預檢請求(preflight)請求的結果能被緩存多久(秒爲單位)。
當瀏覽器的credentials設置爲true時,是否容許瀏覽器讀取response的內容
做爲預檢請求的響應頭,指明瞭實際請求所容許的HTTP方法。
用於預檢請求的響應。其指明瞭實際請求中容許攜帶的首部字段。 以逗號分割。
這些字段通常無需手動設置。
預檢請求或實際請求的源站。
不包含任何路徑,只是服務器的名稱。(不論是否爲跨域,這個字段都被髮送。)
用於預檢請求。其做用是,將實際請求所使用的 HTTP 方法告訴服務器。