日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

CORS预检请求详谈

發(fā)布時間:2024/7/19 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CORS预检请求详谈 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

引言

最近在項目中因前后端部署不同地方,前端在請求后端api時發(fā)生了跨域請求,我們采用CORS(跨域資源共享)來解決跨域請求,這需要前后端的配合來完成。在這一過程中,后端支持了CORS跨域請求后,前端的請求配置可能會調(diào)起CORS的preflight請求,也就是我們所說的預檢請求。對CORS不太熟悉的可能會很容易忽視掉這個問題。下面就來說說CORS的preflight請求。CORS的基本用法不在本文討論中,可以參考阮老師的跨站資源共享CORS詳解。

CORS prefligt請求

preflight請求,就是在發(fā)生cors請求時,瀏覽器檢測到跨域請求,會自動發(fā)出一個OPTIONS請求來檢測本次請求是否被服務器接受。一個OPTIONS請求一般會攜帶下面兩個與CORS相關(guān)的頭:

  • Access-Control-Request-Method : 本次預檢請求的請求方法。
  • Access-Control-Request-Headers:本次請求所攜帶的自定義首部字段。這些字段是導致產(chǎn)生OPTIONS請求的一個原因。后面會講到。

這樣,服務端收到該預檢請求后,會返回與CORS相關(guān)的響應頭。主要會包括下面幾個,但可能還會有其他的有關(guān)CORS字段:

  • Access-Control-Allow-Origin: 服務器允許的跨域請求源
  • Access-Control-Allow-Methods: 服務器允許的請求方法
  • Access-Control-Allow-Headers : 服務器允許的自定義的請求首部字段

服務器通過CORS跨域請求后,下面瀏覽器就會發(fā)生正式的數(shù)據(jù)請求。整個請求過程其實是發(fā)生了兩次請求:一個預檢請求,通過后的實際數(shù)據(jù)請求。這些都可以在瀏覽器網(wǎng)絡(luò)請求中看到。可以參考下圖:

需要注意的是:

1、在上面的兩次請求中,預檢請求只是一個檢查的過程,它不會攜帶任何請求的參數(shù);預檢通過后的請求才會真正的攜帶請求參數(shù)與服務器進行數(shù)據(jù)通信。

2、若服務器對預檢請求沒有任何響應,那么瀏覽器不知道服務器是否支持CORS而不會發(fā)送后續(xù)的實際請求;或者服務器不支持當前的Origin跨域訪問也不會發(fā)送后續(xù)請求。

發(fā)生preflight請求的條件

上面的預檢請求并不是CORS請求的必須的請求過程,在一定的條件下并不需要發(fā)生預檢請求。那么發(fā)生預檢請求的條件是什么呢?根據(jù)HTTP訪問控制(CORS)介紹,其實發(fā)生預檢請求的條件:是否是簡單請求。簡單請求則直接發(fā)送具體的請求而不會產(chǎn)生預檢請求。具體來說如下:

滿足下面的所有條件就不會產(chǎn)生預檢請求,也就是該請求是簡單請求:

  • 請求方法是GET、POST、HEAD其中任意一個

  • 必須是下面定義對CORS安全的首部字段集合,不能是集合之外的其他首部字段。
    Accept、Accept-Language、Content-Language、Content-Type、DPR、Downlink、Save-Data、Viewport-Width、Width。

  • Content-Type的值必須是text/plain、multipart/form-data、application/x-www-form-urlencoded中任意一個值

滿足上面所有的條件才不會發(fā)送預檢請求,在實際項目中我們的請求格式可能是application/json格式編碼,或者使用自定義請求頭都會觸發(fā)CORS的預檢請求。

所以,在項目中是否會觸發(fā)CORS的預檢請求要做到心中有數(shù)。

一個發(fā)送的預檢請求的列子

我們拿一個實際發(fā)生預檢請求的例子來說明整個過程。考慮下面的一個例子:

var xhr = new XMLHttpRequest(); var url = 'http://bar.other/resources/post-here/'; var body = '<?xml version="1.0"?><person><name>Arun</name></person>';function callCors(){if(xhr){xhr.open('POST', url, true);xhr.setRequestHeader('X-PINGOTHER', 'pingpong');xhr.setRequestHeader('Content-Type', 'application/xml');xhr.onreadystatechange = handler;xhr.send(body); } } ......

上面請求中在請求中添加了自定義首部字段X-PINGOTHER,并且請求的Content-Type值application/xml。因此該請求首先會觸發(fā)一個預檢請求。具體的過程見下圖

通過上圖可以看到請求實際產(chǎn)生了2次與服務交互的過程,最后一次會將請求參數(shù)傳給服務器。這樣一個CORS請求過程就完成了。

需要注意的一個有關(guān)CORS的點:

對于附帶身份憑證的請求(即服務器設(shè)置Access-Control-Allow-Credentials: true),服務器不得設(shè)置 Access-Control-Allow-Origin 的值為“*”。否則請求將會失敗。

個人理解是Cookie還是遵循同源策略的,即使因為這個請求是跨域請求,所以每個Origin的Cookie是不能被其他Origin獲取到的,也就是不允許Access-Control-Allow-Origin 的值為“*”。

參考文獻

1、跨域資源共享 CORS 詳解
2、HTTP訪問控制(CORS)
3、CORS - How do 'preflight' an httprequest?

轉(zhuǎn)載于:https://www.cnblogs.com/wonyun/p/CORS_preflight.html

總結(jié)

以上是生活随笔為你收集整理的CORS预检请求详谈的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。