欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一文詳解CORS與預(yù)檢請求

 更新時(shí)間:2023年04月23日 10:47:19   作者:大田稻谷  
這篇文章主要介紹了CORS與預(yù)檢請求,CORS是一套規(guī)范,指導(dǎo)瀏覽器和服務(wù)器之間如何進(jìn)行跨域資源共享,當(dāng)發(fā)送跨域請求時(shí),瀏覽器會先發(fā)送一個(gè)OPTIONS方法的預(yù)檢請求。文中介紹的非常詳細(xì),需要的同學(xué)可以參考一下

CORS

出于安全性,瀏覽器限制腳本內(nèi)發(fā)起的跨源 HTTP 請求。例如,XMLHttpRequest 和 Fetch API 遵循。這意味著使用這些 API 的 Web 應(yīng)用程序只能從加載應(yīng)用程序的同一個(gè)域請求 HTTP 資源,除非響應(yīng)報(bào)文包含了正確 CORS 響應(yīng)頭。

跨源資源共享CORS,通過允許服務(wù)器標(biāo)示除了它自己以外的其他訪問源、協(xié)議或端口,使得瀏覽器允許這些源訪問加載自己的資源。簡單講,就是目標(biāo)資源與當(dāng)前頁面不處于同一個(gè)域時(shí),瀏覽器的同源策略會阻止請求發(fā)出者獲得響應(yīng)數(shù)據(jù)。除非服務(wù)器允許跨域訪問,也就是支持CORS。

這是一些CORS相關(guān)的響應(yīng)頭信息,如果目標(biāo)資源服務(wù)器支持CORS,必須附帶一部分這些頭信息與瀏覽器交互

Access-Control-Allow-Origin:該字段必須出現(xiàn)在服務(wù)器的響應(yīng)中,表示允許跨域的源。如果是通配符( * ),表示接受任意域名的請求。
Access-Control-Allow-Methods:該字段表示接受的請求方法列表,多個(gè)值用逗號分隔。
Access-Control-Allow-Headers:該字段指定了實(shí)際請求可以攜帶的頭部信息,多個(gè)值用逗號分隔。
Access-Control-Allow-Credentials:該字段標(biāo)記是否允許發(fā)送 Cookie。如果為 true,則表示允許發(fā)送 Cookie。
Access-Control-Max-Age:該字段指定了預(yù)檢請求的有效期(單位為秒),即在指定時(shí)間內(nèi)不再發(fā)送預(yù)檢請求,直接發(fā)送實(shí)際請求即可。
Access-Control-Expose-Headers:該字段用于指定哪些頭部信息可以作為響應(yīng)的一部分被獲取到。

預(yù)檢請求

當(dāng)發(fā)送跨域請求時(shí),瀏覽器會先發(fā)送一個(gè)OPTIONS方法的預(yù)檢請求,探測服務(wù)器是否允許實(shí)際請求(POST、GET等)的跨域訪問。服務(wù)器在接收到這個(gè)請求后,會返回一組響應(yīng)頭信息(詳見上文),包含了對CORS的支持情況和允許的請求方法,如果服務(wù)器對跨域請求進(jìn)行了允許,則瀏覽器才會真正地發(fā)送POST請求。如果服務(wù)器對預(yù)檢請求的響應(yīng)頭中拒絕跨域訪問或者根本沒有任何CORS頭信息,瀏覽器會拋出錯誤

因此,瀏覽器需要發(fā)送兩次請求來確認(rèn)服務(wù)器是否允許跨域請求,并確保安全性。

下面將演示觸發(fā)預(yù)檢請求的情況并且演示是處于跨域的環(huán)境下。

攜帶了自定義頭信息的請求

在這種情況下,無論任何請求方法都會觸發(fā)預(yù)檢請求

我們請求 https://api.github.com/,這個(gè)接口支持跨域訪問,我們通過添加自定義請求頭,來觸發(fā)預(yù)檢請求

代碼:

var requestOptions = {
  method: 'GET',
  headers: {
    test: 'test'   // 自定義的頭信息
  },
  redirect: 'follow'
}

fetch("https://api.github.com/", requestOptions)
  .then(response => response.json())
  .then(result => console.log(result))
  .catch(error => console.log('error', error))

運(yùn)行效果:

可以看到明明在代碼里面只有一次請求,可是瀏覽器卻發(fā)出了兩次請求,其中一個(gè)請求就是預(yù)檢請求

看下預(yù)檢請求和真實(shí)請求的請求頭:

不難發(fā)現(xiàn)

  • 真實(shí)請求中,攜帶了自定義請求頭字段
  • 在預(yù)檢請求頭中,access-control-request-headers字段標(biāo)識了真實(shí)請求頭中的自定義字段
  • 在預(yù)檢請求頭中,access-control-request-method字段標(biāo)識了真實(shí)請求所使用的方法,這里是GET方法

總結(jié)來說,預(yù)檢請求會攜帶上真實(shí)請求使用的請求方法和自定義頭字段,去探測服務(wù)器是否允許這樣做。

再來看下預(yù)檢請求的響應(yīng)頭

這些用藍(lán)色方框圈起來的字段可以在上文中找到對應(yīng)的解釋。這里需要說明一點(diǎn),可以從第一張圖看到真實(shí)請求是失敗的,原因在于我們添加的自定義請求頭字段test并不在服務(wù)器允許的請求頭字段中,這一點(diǎn)從預(yù)檢請求的響應(yīng)頭字段access-control-allow-headers很容易看出。

那么如果不攜帶test頭信息,或者換成允許的頭字段,請求會成功,這一點(diǎn)留給讀者自行測試。

PUT,DELETE方法的請求

PUT請求

var raw = JSON.stringify({
  "selected_organization_ids": [
    32,
    91
  ]
})

var requestOptions = {
  method: 'PUT',
  body: raw,
  redirect: 'follow'
}

fetch("https://api.github.com/enterprises//actions/runner-groups//organizations", requestOptions)
  .then(response => response.text())
  .then(result => console.log(result))
  .catch(error => console.log('error', error))

DELETE請求

var requestOptions = {
  method: 'DELETE',
  redirect: 'follow'
}

fetch("https://api.github.com/admin/users//authorizations", requestOptions)
  .then(response => response.text())
  .then(result => console.log(result))
  .catch(error => console.log('error', error))

真實(shí)請求失敗是因?yàn)闆]有傳遞正確的參數(shù)或者接口需要認(rèn)證。

服務(wù)器不允許跨域

上文的演示都是建立在目標(biāo)資源允許跨域訪問的基礎(chǔ)上,下面演示目標(biāo)資源不允許跨域的情況

fetch("https://buy.vmall.com/getSkuRushbuyInfo.json", {
  method: 'get',
  headers: {
    test: 'test'
  }
}).then(res => {
  return res.json()
}).then(res => {
  console.log(res)
})

觀察到預(yù)檢請求頭中沒有任何CORS響應(yīng)頭信息,表示服務(wù)器不允許跨域訪問,這時(shí)候?yàn)g覽器就會報(bào)錯

在代碼層面也是可以捕捉到錯誤的,但是演示代碼中沒有捕獲。

總結(jié)

  • CORS是一套規(guī)范,指導(dǎo)瀏覽器和服務(wù)器之間如何進(jìn)行跨域資源共享
  • 如果請求跨域,對于一些特定類型的請求,瀏覽器會先發(fā)送一次預(yù)檢請求,去探測服務(wù)器是否允許
  • 演示了一部分會觸發(fā)預(yù)檢請求的情況

以上就是一文詳解CORS與預(yù)檢請求的詳細(xì)內(nèi)容,更多關(guān)于CORS與預(yù)檢請求的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論