<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          對CORS OPTIONS預(yù)檢請求的一些思考

          共 2925字,需瀏覽 6分鐘

           ·

          2021-01-04 11:50

          前后端分離模大勢所趨,跨域問題更是老生常談。

          程序員應(yīng)對瀏覽器同源策略的姿勢》一文提到三種跨域請求方案,重點講述了w3c和瀏覽器廠商推出的CORS規(guī)范。

          同源策略??所謂同源是指域名、協(xié)議、端口相同。不同源的瀏覽器腳本(javascript、ActionScript、canvas)在沒有明確授權(quán)的情況下,不能讀寫對方的資源, 這是瀏覽器最基本的安全規(guī)范。

          CORS是w3c和瀏覽器廠商為解決跨域資源共享問題而推出的標(biāo)準(zhǔn)方案:

          瀏覽機(jī)器一旦發(fā)現(xiàn)跨域請求,就會自動添加一些附加的頭信息,有時還會多出一次附加的請求(瀏覽器自動完成,用戶不會察覺),服務(wù)器響應(yīng)特定標(biāo)頭Access-Control-,體現(xiàn)對跨源訪問的授權(quán)態(tài)度。


          今天我主要想要聊一聊CORS中的預(yù)檢請求

          當(dāng)前端使用腳本請求一個跨域資源時,如果是非簡單請求(下文會解釋),瀏覽器會自動幫你先發(fā)出一個OPTIONS查詢請求,稱為預(yù)檢(cors-preflight-request),作用是詢問服務(wù)器當(dāng)前網(wǎng)頁所在的域名是否在服務(wù)器的許可名單之中,以及可以使用哪些HTTP動詞和頭信息字段;只有得到肯定答復(fù),瀏覽器才會發(fā)出正式的跨域請求。

          "預(yù)檢請求“的使用,可以避免跨域請求對服務(wù)器的用戶數(shù)據(jù)產(chǎn)生未預(yù)期的影響。

          該請求header中會包含以下兩個字段:

          • Access-Control-Request-Method: 該字段的值對應(yīng)當(dāng)前請求類型,例如 GET、POST、PUT等等。瀏覽器會自動處理。

          • Access-Control-Request-Headers: 該字段的值對應(yīng)當(dāng)前請求可能會攜帶的額外的自定義header字段名,多個字段用逗號分割。瀏覽器會自動處理,將請求中非簡單的header字段全部列出來,例如標(biāo)識請求流水的x-request-id,用于Auth鑒權(quán)的Authorization 字段。

          對于OPTIONS請求,按照規(guī)范實現(xiàn)的服務(wù)端會響應(yīng)一組HTTP header,但不會返回任何實體內(nèi)容。如果服務(wù)端支持該跨域請求,建議返回204狀態(tài)碼(返回200也可以);如果不支持,建議返回403狀態(tài)碼(返回404或其他錯誤狀態(tài)碼也可以)。

          響應(yīng)的header可以包含以下字段:

          • Access-Control-Allow-Origin: 允許哪些域被允許跨域,例如 http://qq.com 或 https://qq.com,或者設(shè)置為* ,即允許所有域訪問

          • Access-Control-Allow-Credentials: 是否攜帶票據(jù)訪問(對應(yīng)fetch方法中credentials),當(dāng)該值為true時,Access-Control-Allow-Origin 不允許設(shè)置為*

          • Access-Control-Allow-Methods: 標(biāo)識該資源支持哪些方法,例如:POST, GET, PUT, DELETE

          • Access-Control-Allow-Headers: 標(biāo)識允許哪些額外的自定義 header 字段和非簡單值的字段

          • Access-Control-Max-Age: 表示可以緩存Access-Control-Allow-Methods和Access-Control-Allow-Headers提供的信息多長時間,單位秒,由服務(wù)端和瀏覽器默認(rèn)值共同決定。

          • Access-Control-Expose-Headers: 通過該字段指出哪些額外的 header 可以被支持。

          由此可見,當(dāng)觸發(fā)預(yù)檢時,一次AJAX請求會消耗掉兩個TTL,嚴(yán)重影響性能。

          那么如何節(jié)省掉OPTIONS請求來提升性能呢?從上文可以看出,有兩個方案:

          1. 發(fā)出簡單請求

          只要同時滿足以下兩個條件,就屬于簡單請求
          (1)使用下列方法之一:

          • head
          • get
          • post

          (2)請求的Heder是

          • Accept
          • Accept-Language
          • Content-Language
          • Content-Type: 只限于三個值:application/x-www-form-urlencoded、multipart/form-data、text/plain

          不同時滿足上面的兩個條件,就屬于非簡單請求。很明顯,我們常見的Post請求且Content-Type=application/json也屬于非簡單請求,也會觸發(fā)預(yù)檢請求。

          >? ?如果不方便改造為簡單請求,只有使用方案2了。

          1. 服務(wù)器端設(shè)置Access-Control-Max-Age字段

          當(dāng)?shù)谝淮握埱笤揢RL時會發(fā)出OPTIONS請求,瀏覽器會根據(jù)返回的Access-Control-Max-Age字段緩存該OPTIONS預(yù)檢請求的響應(yīng)結(jié)果。在緩存有效期內(nèi),該資源的請求(URL和header字段都相同的情況下)不會再觸發(fā)預(yù)檢。(chrome 打開控制臺可以看到,當(dāng)服務(wù)器響應(yīng)Access-Control-Max-Age時只有第一次請求會有預(yù)檢,后面不會了。注意要開啟緩存,去掉disable cache勾選)

          但是要注意的是,該緩存只針對這一個請求 URL 和相同的 header,無法針對整個域或者模糊匹配 URL 做緩存(當(dāng)然也可以考慮封裝一下,固定一個接口地址,傳不同的body內(nèi)容)。

          以上便是對CORS OPTIONS預(yù)檢請求的一些思考,希望對同學(xué)們有所幫助!

          最后是Abp vNtext配置CORS的示例:

          private?void?ConfigureCors(ServiceConfigurationContext?context,?IConfiguration?configuration)
          {
          ?????context.Services.AddCors(options?=>
          ?????{
          ???????//?無阻塞跨域
          ????????options.AddPolicy(DefaultCorsPolicyName,?builder?=>
          ???????{
          ????????builder.SetIsOriginAllowed(_?=>?true)
          ?????????????.AllowCredentials()
          ?????????????.AllowAnyHeader()
          ?????????????.WithMethods(HttpMethods.Get,?HttpMethods.Post,?HttpMethods.Put,?HttpMethods.Delete)
          ????????????????????.SetPreflightMaxAge(TimeSpan.FromHours(24));
          ????????});
          ?????});
          }
          - https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age
          -??程序員應(yīng)對瀏覽器同源策略的姿勢




          關(guān)注并星標(biāo)我們
          更多干貨及最佳實踐分享


          瀏覽 50
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日本wwwxxxx | 欧美色哟哟哟 | 一区二区熟女 | 毛片内射 | 婷婷五月天激情小说视频 |