Header增加字段導(dǎo)致跨域OPTIONS請(qǐng)求不成功

今天團(tuán)隊(duì)關(guān)于跨域請(qǐng)求遇到了一個(gè)小問題,在前后端分離請(qǐng)求中會(huì)觸發(fā)跨域OPTIONS請(qǐng)求,而后端使用攔截器處理OPTIONS請(qǐng)求時(shí),前端無法正常繼續(xù)GET請(qǐng)求。主要是對(duì)一個(gè)已經(jīng)在使用的接口增加驗(yàn)證碼功能,但是又不能修改原接口參數(shù)字段,故在Header中增加了一個(gè)自定義字段。

先是整理了瀏覽器對(duì)于跨域請(qǐng)求的定義,對(duì)跨域請(qǐng)求區(qū)分為“簡單請(qǐng)求”與“非簡單請(qǐng)求”。

? “簡單請(qǐng)求”滿足以下特征:

(1) 請(qǐng)求方法是以下三種方法之一:

? ? ?HEAD、GET、POST

(2)HTTP的頭信息不超出以下幾種字段:

? ? ?Accept

? ? ?Accept-Language

? ? ?Content-Language

? ? ?Last-Event-ID

? ? ?Content-Type:

? ? ? ? ?application/x-www-form-urlencoded、 multipart/form-data、text/plain

? ?不滿足這些特征的請(qǐng)求稱為“非簡單請(qǐng)求”,例如:content-type=applicaiton/json , method = PUT/DELETE,HTTP頭自定義字段(這次我們遇到的問題就是增加了自定義字段code)

1、非簡單請(qǐng)求的預(yù)檢測(cè)

如果我們發(fā)送的跨域請(qǐng)求為“非簡單請(qǐng)求”,瀏覽器會(huì)在發(fā)出此請(qǐng)求之前首先發(fā)送一個(gè)請(qǐng)求類型為OPTIONS的“預(yù)檢請(qǐng)求”,驗(yàn)證請(qǐng)求源是否為服務(wù)端允許源,這些過程對(duì)于開發(fā)者來說是感覺不到的,由瀏覽器代理。

2、請(qǐng)求的過程

簡單請(qǐng)求

瀏覽器判斷跨域?yàn)楹唵握?qǐng)求時(shí)候,會(huì)在Request Header中添加 Origin (協(xié)議 + 域名 + 端口)字段 , 它表示我們的請(qǐng)求源,服務(wù)端會(huì)將該字段作為跨源標(biāo)志。

服務(wù)端接收到此次請(qǐng)求后 , 首先會(huì)判斷Origin是否在允許源(由服務(wù)端決定)范圍之內(nèi),如果驗(yàn)證通過,服務(wù)端會(huì)在Response Header 添加 Access-Control-Allow-Origin、Access-Control-Allow-Credentials等字段。

必須字段:

  Access-Control-Allow-Origin:表示服務(wù)端允許的請(qǐng)求源,*標(biāo)識(shí)任何外域,多個(gè)源 , 分隔

可選字段:

  Access-Control-Allow-Credentials:false 表示是否允許發(fā)送Cookie。設(shè)置為true,同時(shí)ajax請(qǐng)求設(shè)置withCredentials = true,瀏覽器的cookie就能發(fā)送到服務(wù)端;

瀏覽器收到Respnose后會(huì)判斷自己的源是否存在 Access-Control-Allow-Origin允許源中,如果不存在,會(huì)拋出“同源檢測(cè)異?!?。

總結(jié):簡單請(qǐng)求只需要服務(wù)端在接受到攜帶Origin字段的跨域請(qǐng)求后,在response header中添加Access-Control-Allow-Origin等字段給瀏覽器做同源判斷。

非簡單請(qǐng)求

進(jìn)行非簡單請(qǐng)求時(shí)候 , 瀏覽器會(huì)首先發(fā)出類型為OPTIONS的“預(yù)檢請(qǐng)求”,服務(wù)端對(duì)“預(yù)檢請(qǐng)求”處理,并對(duì)Response Header添加驗(yàn)證字段,客戶端接受到預(yù)檢請(qǐng)求的返回值進(jìn)行一次請(qǐng)求預(yù)判斷,驗(yàn)證通過后,主請(qǐng)求發(fā)起。


這里可以看到,瀏覽器連續(xù)發(fā)送了兩個(gè)請(qǐng)求 , 第一個(gè)就是“預(yù)檢請(qǐng)求”,類型為OPTIONS,此處也需要按簡單請(qǐng)求中一樣,在Response Header 添加 Access-Control-Allow-Origin、Access-Control-Allow-Credentials等字段。但此處要注意的是,因?yàn)槲覀冊(cè)贕ET請(qǐng)求的Request Headers中設(shè)置了code這個(gè)屬性 ,所以預(yù)檢請(qǐng)求的Request Headers中的Access-Control-Request-Headers的值也為code,那Response?Headers中的Access-Control-Allow-Headers必須攜帶code,否則OPTIONS請(qǐng)求會(huì)失敗。

預(yù)檢請(qǐng)求通過后,主請(qǐng)求與簡單請(qǐng)求一致。

總結(jié):非簡單請(qǐng)求需要服務(wù)端對(duì)OPTIONS類型的請(qǐng)求做處理!

3、手動(dòng)解決的辦法

在服務(wù)端處理過程時(shí),在響應(yīng)頭中增加以下幾部分的內(nèi)容即可:

Access-Control-Allow-Origin服務(wù)器能接受的跨域請(qǐng)求來源,配置?主機(jī)地址(http://www.xxx.com,如有端口也要加上), * 表示任意地址都行

Access-Control-Allow-Headers?表示能接受的http頭部,此處要加入你自己構(gòu)建的頭部字段,如上面的code

Access-Control-Allow-Methods?表示能接受的http mothed ,看使用情況加上,如GET、POST、OPTIONS等

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容