<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>

          post為什么會(huì)發(fā)送兩次請求?

          共 5650字,需瀏覽 12分鐘

           ·

          2024-04-11 13:00

          戳上方藍(lán)字“ Java金融 ”關(guān)注!

          在前段時(shí)間的一次面試中,被問到了一個(gè)如標(biāo)題這樣的問題。要想好好地去回答這個(gè)問題,這里牽扯到的知識點(diǎn)也是比較多的。

          那么接下來這篇文章我們就一點(diǎn)一點(diǎn)開始引出這個(gè)問題。

          同源策略

          在瀏覽器中,內(nèi)容是很開放的,任何資源都可以接入其中,如 JavaScript 文件、圖片、音頻、視頻等資源,甚至可以下載其他站點(diǎn)的可執(zhí)行文件。

          但也不是說瀏覽器就是完全自由的,如果不加以控制,就會(huì)出現(xiàn)一些不可控的局面,例如會(huì)出現(xiàn)一些安全問題,如:

          • 跨站腳本攻擊(XSS)

          • SQL 注入攻擊

          • OS 命令注入攻擊

          • HTTP 首部注入攻擊

          • 跨站點(diǎn)請求偽造(CSRF)

          • 等等......

          如果這些都沒有限制的話,對于我們用戶而言,是相對危險(xiǎn)的,因此需要一些安全策略來保障我們的隱私和數(shù)據(jù)安全。

          這就引出了最基礎(chǔ)、最核心的安全策略:同源策略。

          什么是同源策略

          同源策略是一個(gè)重要的安全策略,它用于限制一個(gè)源的文檔或者它加載的腳本如何能與另一個(gè)源的資源進(jìn)行交互。

          如果兩個(gè) URL 的協(xié)議、主機(jī)和端口都相同,我們就稱這兩個(gè) URL 同源。

          • 協(xié)議:協(xié)議是定義了數(shù)據(jù)如何在計(jì)算機(jī)內(nèi)和之間進(jìn)行交換的規(guī)則的系統(tǒng),例如 HTTP、HTTPS。

          • 主機(jī):是已連接到一個(gè)計(jì)算機(jī)網(wǎng)絡(luò)的一臺電子計(jì)算機(jī)或其他設(shè)備。網(wǎng)絡(luò)主機(jī)可以向網(wǎng)絡(luò)上的用戶或其他節(jié)點(diǎn)提供信息資源、服務(wù)和應(yīng)用。使用 TCP/IP 協(xié)議族參與網(wǎng)絡(luò)的計(jì)算機(jī)也可稱為 IP 主機(jī)。

          • 端口:主機(jī)是計(jì)算機(jī)到計(jì)算機(jī)之間的通信,那么端口就是進(jìn)程到進(jìn)程之間的通信。

          如下表給出了與 URL http://store.company.com:80/dir/page.html 的源進(jìn)行對比的示例:

          4506f0e38dcbe9a792eba91eb812eb3b.webp

          同源策略主要表現(xiàn)在以下三個(gè)方面:DOM、Web 數(shù)據(jù)和網(wǎng)絡(luò)。

          • DOM 訪問限制:同源策略限制了網(wǎng)頁腳本(如 JavaScript)訪問其他源的 DOM。這意味著通過腳本無法直接訪問跨源頁面的 DOM 元素、屬性或方法。這是為了防止惡意網(wǎng)站從其他網(wǎng)站竊取敏感信息。

          • Web 數(shù)據(jù)限制:同源策略也限制了從其他源加載的 Web 數(shù)據(jù)(例如 XMLHttpRequest 或 Fetch API)。在同源策略下,XMLHttpRequest 或 Fetch 請求只能發(fā)送到與當(dāng)前網(wǎng)頁具有相同源的目標(biāo)。這有助于防止跨站點(diǎn)請求偽造(CSRF)等攻擊。

          • 網(wǎng)絡(luò)通信限制:同源策略還限制了跨源的網(wǎng)絡(luò)通信。瀏覽器會(huì)阻止從一個(gè)源發(fā)出的請求獲取來自其他源的響應(yīng)。這樣做是為了確保只有受信任的源能夠與服務(wù)器進(jìn)行通信,以避免惡意行為。

          出于安全原因,瀏覽器限制從腳本內(nèi)發(fā)起的跨源 HTTP 請求,XMLHttpRequest 和 Fetch API,只能從加載應(yīng)用程序的同一個(gè)域請求 HTTP 資源,除非使用 CORS 頭文件

          CORS

          對于瀏覽器限制這個(gè)詞,要著重解釋一下:不一定是瀏覽器限制了發(fā)起跨站請求,也可能是跨站請求可以正常發(fā)起,但是返回結(jié)果被瀏覽器攔截了。

          瀏覽器將不同域的內(nèi)容隔離在不同的進(jìn)程中,網(wǎng)絡(luò)進(jìn)程負(fù)責(zé)下載資源并將其送到渲染進(jìn)程中,但由于跨域限制,某些資源可能被阻止加載到渲染進(jìn)程。如果瀏覽器發(fā)現(xiàn)一個(gè)跨域響應(yīng)包含了敏感數(shù)據(jù),它可能會(huì)阻止腳本訪問這些數(shù)據(jù),即使網(wǎng)絡(luò)進(jìn)程已經(jīng)獲得了這些數(shù)據(jù)。CORB 的目標(biāo)是在渲染之前盡早阻止惡意代碼獲取跨域數(shù)據(jù)。

          CORB 是一種安全機(jī)制,用于防止跨域請求惡意訪問跨域響應(yīng)的數(shù)據(jù)。渲染進(jìn)程會(huì)在 CORB 機(jī)制的約束下,選擇性地將哪些資源送入渲染進(jìn)程供頁面使用。

          例如,一個(gè)網(wǎng)頁可能通過 AJAX 請求從另一個(gè)域的服務(wù)器獲取數(shù)據(jù)。雖然某些情況下這樣的請求可能會(huì)成功,但如果瀏覽器檢測到請求返回的數(shù)據(jù)可能包含惡意代碼或與同源策略沖突,瀏覽器可能會(huì)阻止網(wǎng)頁訪問返回的數(shù)據(jù),以確保用戶的安全。

          跨源資源共享(Cross-Origin Resource Sharing,CORS)是一種機(jī)制,允許在受控的條件下,不同源的網(wǎng)頁能夠請求和共享資源。由于瀏覽器的同源策略限制了跨域請求,CORS 提供了一種方式來解決在 Web 應(yīng)用中進(jìn)行跨域數(shù)據(jù)交換的問題。

          CORS 的基本思想是,服務(wù)器在響應(yīng)中提供一個(gè)標(biāo)頭(HTTP 頭),指示哪些源被允許訪問資源。瀏覽器在發(fā)起跨域請求時(shí)會(huì)先發(fā)送一個(gè)預(yù)檢請求(OPTIONS 請求)到服務(wù)器,服務(wù)器通過設(shè)置適當(dāng)?shù)?CORS 標(biāo)頭來指定是否允許跨域請求,并指定允許的請求源、方法、標(biāo)頭等信息。

          簡單請求

          不會(huì)觸發(fā) CORS 預(yù)檢請求。這樣的請求為 簡單請求,。若請求滿足所有下述條件,則該請求可視為 簡單請求

          1. HTTP 方法限制:只能使用 GET、HEAD、POST 這三種 HTTP 方法之一。如果請求使用了其他 HTTP 方法,就不再被視為簡單請求。

          2. 自定義標(biāo)頭限制:請求的 HTTP 標(biāo)頭只能是以下幾種常見的標(biāo)頭:AcceptAccept-LanguageContent-LanguageLast-Event-IDContent-Type(僅限于 application/x-www-form-urlencodedmultipart/form-datatext/plain)。HTML 頭部 header field 字段:DPR、Download、Save-Data、Viewport-Width、WIdth。如果請求使用了其他標(biāo)頭,同樣不再被視為簡單請求。

          3. 請求中沒有使用 ReadableStream 對象。

          4. 不使用自定義請求標(biāo)頭:請求不能包含用戶自定義的標(biāo)頭。

          5. 請求中的任意 XMLHttpRequestUpload 對象均沒有注冊任何事件監(jiān)聽器;XMLHttpRequestUpload 對象可以使用 XMLHttpRequest.upload 屬性訪問

          預(yù)檢請求

          非簡單請求的 CORS 請求,會(huì)在正式通信之前,增加一次 HTTP 查詢請求,稱為 預(yù)檢請求

          需預(yù)檢的請求要求必須首先使用 OPTIONS 方法發(fā)起一個(gè)預(yù)檢請求到服務(wù)器,以獲知服務(wù)器是否允許該實(shí)際請求。預(yù)檢請求 的使用,可以避免跨域請求對服務(wù)器的用戶數(shù)據(jù)產(chǎn)生未預(yù)期的影響。

          例如我們在掘金上刪除一條沸點(diǎn):

          19f053dd11a47a04291849d93a225e0e.webp

          它首先會(huì)發(fā)起一個(gè)預(yù)檢請求,預(yù)檢請求的頭信息包括兩個(gè)特殊字段:

          • Access-Control-Request-Method:該字段是必須的,用來列出瀏覽器的 CORS 請求會(huì)用到哪些 HTTP 方法,上例是 POST。

          • Access-Control-Request-Headers:該字段是一個(gè)逗號分隔的字符串,指定瀏覽器 CORS 請求會(huì)額外發(fā)送的頭信息字段,上例是 content-type,x-secsdk-csrf-token

          • access-control-allow-origin:在上述例子中,表示 https://juejin.cn 可以請求數(shù)據(jù),也可以設(shè)置為* 符號,表示統(tǒng)一任意跨源請求。

          • access-control-max-age:該字段可選,用來指定本次預(yù)檢請求的有效期,單位為秒。上面結(jié)果中,有效期是 1 天(86408 秒),即允許緩存該條回應(yīng) 1 天(86408 秒),在此期間,不用發(fā)出另一條預(yù)檢請求。

          一旦服務(wù)器通過了 預(yù)檢請求,以后每次瀏覽器正常的 CORS 請求,就都跟簡單請求一樣,會(huì)有一個(gè) Origin 頭信息字段。服務(wù)器的回應(yīng),也都會(huì)有一個(gè) Access-Control-Allow-Origin 頭信息字段。

          d2d69559b62f52eabf28f0a2ae485478.webp

          上面頭信息中,Access-Control-Allow-Origin 字段是每次回應(yīng)都必定包含的。

          附帶身份憑證的請求與通配符

          在響應(yīng)附帶身份憑證的請求時(shí):

          • 為了避免惡意網(wǎng)站濫用 Access-Control-Allow-Origin 頭部字段來獲取用戶敏感信息,服務(wù)器在設(shè)置時(shí)不能將其值設(shè)為通配符 *。相反,應(yīng)該將其設(shè)置為特定的域,例如:Access-Control-Allow-Origin: https://juejin.cn。通過將 Access-Control-Allow-Origin 設(shè)置為特定的域,服務(wù)器只允許來自指定域的請求進(jìn)行跨域訪問。這樣可以限制跨域請求的范圍,避免不可信的域獲取到用戶敏感信息。

          • 為了避免潛在的安全風(fēng)險(xiǎn),服務(wù)器不能將 Access-Control-Allow-Headers 的值設(shè)為通配符 *。這是因?yàn)椴皇芟拗频恼埱箢^可能被濫用。相反,應(yīng)該將其設(shè)置為一個(gè)包含標(biāo)頭名稱的列表,例如:Access-Control-Allow-Headers: X-PINGOTHER, Content-Type。通過將 Access-Control-Allow-Headers 設(shè)置為明確的標(biāo)頭名稱列表,服務(wù)器可以限制哪些自定義請求頭是允許的。只有在允許的標(biāo)頭列表中的頭部字段才能在跨域請求中被接受。

          • 為了避免潛在的安全風(fēng)險(xiǎn),服務(wù)器不能將 Access-Control-Allow-Methods 的值設(shè)為通配符 *。這樣做將允許來自任意域的請求使用任意的 HTTP 方法,可能導(dǎo)致濫用行為的發(fā)生。相反,應(yīng)該將其設(shè)置為一個(gè)特定的請求方法名稱列表,例如:Access-Control-Allow-Methods: POST, GET。通過將 Access-Control-Allow-Methods 設(shè)置為明確的請求方法列表,服務(wù)器可以限制哪些方法是允許的。只有在允許的方法列表中的方法才能在跨域請求中被接受和處理。

          • 對于附帶身份憑證的請求(通常是 Cookie),

          這是因?yàn)檎埱蟮臉?biāo)頭中攜帶了 Cookie 信息,如果 Access-Control-Allow-Origin 的值為 *,請求將會(huì)失敗。而將 Access-Control-Allow-Origin 的值設(shè)置為 https://juejin。cn,則請求將成功執(zhí)行。

          另外,響應(yīng)標(biāo)頭中也攜帶了 Set-Cookie 字段,嘗試對 Cookie 進(jìn)行修改。如果操作失敗,將會(huì)拋出異常。

          為什么本地使用 webpack 進(jìn)行 dev 開發(fā)時(shí),不需要服務(wù)器端配置 cors 的情況下訪問到線上接口?

          當(dāng)你在本地通過 Ajax 或其他方式請求線上接口時(shí),由于瀏覽器的同源策略,會(huì)出現(xiàn)跨域的問題。但是在服務(wù)器端并不會(huì)出現(xiàn)這個(gè)問題。

          它是通過 Webpack Dev Server 來實(shí)現(xiàn)這個(gè)功能。當(dāng)你在瀏覽器中發(fā)送請求時(shí),請求會(huì)先被 Webpack Dev Server 捕獲,然后根據(jù)你的代理規(guī)則將請求轉(zhuǎn)發(fā)到目標(biāo)服務(wù)器,目標(biāo)服務(wù)器返回的數(shù)據(jù)再經(jīng)由 Webpack Dev Server 轉(zhuǎn)發(fā)回瀏覽器。這樣就繞過了瀏覽器的同源策略限制,使你能夠在本地開發(fā)環(huán)境中訪問線上接口。

          參考文章
          • CORS 簡單請求+預(yù)檢請求(徹底理解跨域) [1]

          • 跨域資源共享 CORS 詳解 [2]

          • 跨源資源共享(CORS) [3]

          總結(jié)

          預(yù)檢請求是在進(jìn)行跨域資源共享 CORS 時(shí),由瀏覽器自動(dòng)發(fā)起的一種 OPTIONS 請求。它的存在是為了保障安全,并允許服務(wù)器決定是否允許跨域請求。

          跨域請求是指在瀏覽器中向不同域名、不同端口或不同協(xié)議的資源發(fā)送請求。出于安全原因,瀏覽器默認(rèn)禁止跨域請求,只允許同源策略。而當(dāng)網(wǎng)頁需要進(jìn)行跨域請求時(shí),瀏覽器會(huì)自動(dòng)發(fā)送一個(gè)預(yù)檢請求,以確定是否服務(wù)器允許實(shí)際的跨域請求。

          預(yù)檢請求中包含了一些額外的頭部信息,如 Origin 和 Access-Control-Request-Method 等,用于告知服務(wù)器實(shí)際請求的方法和來源。服務(wù)器收到預(yù)檢請求后,可以根據(jù)這些頭部信息,進(jìn)行驗(yàn)證和授權(quán)判斷。如果服務(wù)器認(rèn)可該跨域請求,將返回一個(gè)包含 Access-Control-Allow-Origin 等頭部信息的響應(yīng),瀏覽器才會(huì)繼續(xù)發(fā)送實(shí)際的跨域請求。

          使用預(yù)檢請求機(jī)制可以有效地防范跨域請求帶來的安全風(fēng)險(xiǎn),保護(hù)用戶數(shù)據(jù)和隱私。

          整個(gè)完整的請求流程有如下圖所示:

          05dc5ed6b37c51a1543f69b8fd8354b6.webp

          參考資料

          [1]

          CORS 簡單請求+預(yù)檢請求(徹底理解跨域): https://github.com/amandakelake/blog/issues/62

          [2]

          跨域資源共享 CORS 詳解: http://www.ruanyifeng.com/blog/2016/04/cors.html

          [3]

          跨源資源共享(CORS): developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS#預(yù)檢請求

          感謝閱讀,希望對你有所幫助 :)    來源:

          juejin.cn/post/7269952188927017015

              
                  后端專屬技術(shù)群
                
                

          構(gòu)建高質(zhì)量的技術(shù)交流社群,歡迎從事編程開發(fā)、技術(shù)招聘HR進(jìn)群,也歡迎大家分享自己公司的內(nèi)推信息,相互幫助,一起進(jìn)步!

          文明發(fā)言,以交流技術(shù)職位內(nèi)推行業(yè)探討為主

          廣告人士勿入,切勿輕信私聊,防止被騙

          加我好友,拉你進(jìn)群
          瀏覽 25
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <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>
                  日欧操逼电影 | 欧美成人精品在线播放 | 狼人入口国产 | 天天天做夜夜夜夜爽无码 | 18av在线播放 |