CORS跨域請求

前言

相信不少前端開發人員都會遇到跨域請求的問題。或者在面試的時候,都會被問到如何解決跨域問題,有多少人是以爲這個是前端必需要去解決的問題?實際上這個問題要先後端共同去解決的,咱們經常使用的方法不管是用jsonp仍是cors都是須要先後端一塊兒去完成的。之因此寫這篇文章就是最近在使用cors時,遇到了一些問題,在此進行總結一下加深印象。前端

項目狀況

項目要求先後端須要部署在不一樣的域名或者是不一樣的端口下面,天然就會存在請求跨域的問題了,跟後臺協商好用的解決方案是使用CORS方式。請求須要cookie,須要自定義請求頭‘x-requested-with’,如下是後臺設置的代碼,正常這樣設置是沒問題的了 面試

前端也設置了請求頭 withCredentials = true;最後的結果仍是不行,這就很奇怪了,百度看了不少解決方案都是同樣的代碼,爲何這裏就不行?請求攜帶cookie或有自定義請求頭,origin也動態設置成對應發出請求的origin了。

postman、fetch測試

在postman上使用一樣的請求(無‘x-requested-with’請求頭,也無cookie)切換method進行測試,只有get和post會有狀態碼返回,其餘的連狀態碼都沒有,看上圖的設置,options和delete理應也會有狀態碼返回的纔對,這是就判斷是否是後臺代碼在哪一個地方進行了攔截,連進CorsUtils的機會都沒有。用fetch測試,帶上‘x-requested-with’在控制檯看到Request Method爲OPTIONS,無響應體。另外在項目裏測試的是一個post請求,攜帶了cookie和自定義請求頭。接下來就瞭解下cors的存在的場景吧。json

cors場景

cors存在三種跨域請求場景,分別是簡單跨域請求帶預檢(Preflighted)的跨域請求附帶身份憑證的請求後端

簡單跨域請求

當知足如下條件時,瀏覽器會認爲是簡單請求跨域

  • 請求方法是get,post或head,且Content-Type的值爲application/x-www-form-urlencoded, multipart/form-data或着text/plain中的一個值;
  • 無自定義請求頭

此時「Access-Control-Allow-Origin」設置成「*」,便可跨域訪問,也能夠設置成指定的域名,在上面所說的項目中也驗證了這點,確實是能夠跨域請求成功了。瀏覽器

帶預檢(Preflighted)的跨域請求

當知足如下任一條件時,瀏覽器會先發送一個OPTIONS的預檢請求,當預檢請求成功後,纔會發送真正的請求cookie

  • 請求方法是put、delete、connect、options、trace和patch其中之一;
  • content-type的值是application/x-www-form-urlencoded, multipart/form-data和text/plain以外的;
  • 攜帶自定義請求頭的;

到這裏,結合項目用的請求(就是這裏所說的帶預檢的請求)和上面的測試狀況,就讓後臺去檢查他使用的後臺框架是否是在哪裏對get和post之外的請求攔截調了,後臺去檢查後果真是後臺框架上作了限制,根本就沒有機會進入到上圖粘出來的程序。至於後臺作了什麼我就不是很懂了這裏就略過了。app

附帶身份憑證的請求

另外項目須要作會話處理,須要使用到cookie,後臺設置了「Access-Control-Allow-Credentials」爲 true,前端也設置了請求頭 withCredentials = true;這樣請求就能把cookie帶上了。這裏要注意的是當請求須要附帶身份憑證時,「Access-Control-Allow-Origin」要設置成指定域名,建議有跨域要求都設置成動態域名,不要設置「*」避免沒必要要的麻煩。cors

總結

以上是在開發過程當中遇到的問題,針對這個問題的排查過程作了個回憶,並對cors跨域請求的知識作了個鞏固。紮實的基礎會對問題的排查節省不少時間,多總結,多積累。框架

若有錯誤的理解,煩請指出,謝謝閱讀。

相關文章
相關標籤/搜索