談到跨域,不論前端仍是後端,多少有點談虎色變,面試中也常會問到這些問題,瀏覽器和服務器端到底怎麼作才能跨域,他們都作了什麼?html
同源,字面意義是相同的源頭,即同一個web服務器(好比tomcat啓動的一個實例),比如一個家庭;跨域就是從一個web服務器向另外一個服務器發送或獲取數據,比如去鄰居家拿東西。之因此要作跨域限制,是爲了安全,你不能從鄰居家直接拿吧,總得問過人家。前端
那麼怎麼來判斷同源?就看一個web服務器的根本三要素:協議、web服務器域名、端口號。web
好比:當前頁面的地址是http://myhost.com:8080/index
,源就是http://myhost.com:8080
,當新請求的協議、域名、端口號與之徹底一致便是同源,不然是跨域。面試
對於下面發送的請求,瀏覽器的判決以下:ajax
http://
www.myhost.com:8080/users
跨域 -> 域名必須徹底一致://myhost.com:8080/users
跨域 -> 協議必須一致https://myhost.com:
9000/users
跨域 -> 端口必須一致https://myhost.com/users
跨域 -> 端口必須一致(沒有端口也是不一致)https://myhost.com:8080/profile/users
同源假設咱們點擊一個按鈕去獲取數據,獲取數據的請求準備從瀏覽器發出,這時瀏覽器先會檢測這條請求是同源仍是跨域,也就是與按鈕所在頁面的地址是同源仍是跨域,若是是同源,好說,直接發送出去;若是是跨域的請求,那就得hold住先,瀏覽器會在請求的http header中加上一個Origin字段,標明這個請求是從哪裏發出來的,例如: Origin:http://neighbour.com:9000
,這樣服務器端好辨識是本身家人來取東西,仍是隔壁老王來借東西了。json
那些作檢測、加header字段等事情全是瀏覽器作,對於前端開發者來講,什麼事都不用幹,ajax請求平時怎麼發送,跨域時還怎麼發送。可見,跨域對於前端沒影響,關鍵在於服務器端。後端
每一個web服務器就像一個家庭。好鄰居要吃螃蟹來借點醋,這沒問題;壞鄰居家有醋要來借點螃蟹,這不幹。跨域
服務器收到請求會給與響應,響應的header裏寫明跨域的配置信息,告訴瀏覽器,它容許哪些域名發來的請求訪問,哪些method能夠執行。瀏覽器收到響應後自動判斷能不能真正執行請求。瀏覽器
假設服務器域名是http://rich.com:8080
,它收到了一個從http://neighbour.com:9000
發來的請求http://rich.com:9000/borrow-vinegar
,服務器響應它,在響應中寫明本服務器支持哪些域名能夠訪問,哪些method能夠執行,瀏覽器收到後作匹配,再斷定。緩存
那麼,服務器有哪些斷定的規則呢?
一個支持CORS的web服務器,有以下的斷定字段,他們會在響應的header中寫明
其中Access-Control-Allow-Origin
(訪問控制之容許的源),在響應的http header中必須有的,表示容許訪問本服務器的源頭Origin
(域名),能夠是特定的域名列表,用逗號分隔,也能夠是通配符 *
,表示支持任意域名的訪問。
除了限定源頭Origin
,還會限制請求的方法Method
,Header
。
如,若是服務器設定Access-Control-Allow-Methods:GET
,那麼跨域的POST請求沒法在這個服務器執行。
Access-Control-Allow-origin
字段,若配置過域名,則返回Access-Control-Allow-origin+ 對應配置規則裏的域名
的方式。跨域的請求分兩種,一種是簡單請求,一種是非簡單請求(廢話)。
簡單請求,方法僅限於 HEAD,GET或POST
,且Header的字段不超過如下字段:
簡單請求瀏覽器會直接在請求的Header加上Origin字段再發送;非簡單請求瀏覽器則會先發送一次預檢請求,根據預檢請求的結果,決定是否正式發送請求。
詳情能夠訪問阮一峯的日誌:跨域資源共享 CORS 詳解