0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

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

jf_ro2CN3Fa ? 來源:CSDN ? 2023-09-25 09:57 ? 次閱讀

前言

最近博主在字節(jié)面試中遇到這樣一個面試題,這個問題也是前端面試的高頻問題,因為在前端開發(fā)的日常開發(fā)中我們總是會與post請求打交道,一個小小的post請求也是牽扯到很多知識點的,博主在這給大家細細道來。

同源策略

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

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

跨站腳本攻擊(XSS)

SQL 注入攻擊

OS 命令注入攻擊

HTTP 首部注入攻擊

跨站點請求偽造(CSRF)

等等…

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

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

什么是同源策略

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

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

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

主機:是已連接到一個計算機網絡的一臺電子計算機或其他設備。網絡主機可以向網絡上的用戶或其他節(jié)點提供信息資源、服務和應用。使用 TCP/IP 協(xié)議族參與網絡的計算機也可稱為 IP 主機。

端口:主機是計算機到計算機之間的通信,那么端口就是進程到進程之間的通信。

如下表給出了與 URL 的源進行對比的示例:

fb754dc8-5a92-11ee-939d-92fbcf53809c.png

同源策略主要表現在以下三個方面:DOM、Web 數據和網絡。

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

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

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

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

CORS

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

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

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

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

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

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

簡單請求

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

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

自定義標頭限制:請求的 HTTP 標頭只能是以下幾種常見的標頭:Accept、Accept-Language、Content-Language、Last-Event-ID、Content-Type(僅限于 application/x-www-form-urlencoded、multipart/form-data、text/plain)。HTML 頭部 header field 字段:DPR、Download、Save-Data、Viewport-Width、WIdth。如果請求使用了其他標頭,同樣不再被視為簡單請求。

請求中沒有使用 ReadableStream 對象。

不使用自定義請求標頭:請求不能包含用戶自定義的標頭。

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

預檢請求

非簡單請求的 CORS 請求,會在正式通信之前,增加一次 HTTP 查詢請求,稱為 預檢請求。

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

例如我在自己的網站上刪除一條記錄:

fb80d9ea-5a92-11ee-939d-92fbcf53809c.png

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

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

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

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

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

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

fb9f90a6-5a92-11ee-939d-92fbcf53809c.png

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

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

在響應附帶身份憑證的請求時:

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

為了避免潛在的安全風險,服務器不能將 Access-Control-Allow-Headers 的值設為通配符 *。這是因為不受限制的請求頭可能被濫用。相反,應該將其設置為一個包含標頭名稱的列表,例如:Access-Control-Allow-Headers: X-PINGOTHER, Content-Type。通過將 Access-Control-Allow-Headers 設置為明確的標頭名稱列表,服務器可以限制哪些自定義請求頭是允許的。只有在允許的標頭列表中的頭部字段才能在跨域請求中被接受。

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

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

這是因為請求的標頭中攜帶了 Cookie 信息,如果 Access-Control-Allow-Origin 的值為 *,請求將會失敗。而將 Access-Control-Allow-Origin 的值設置為 https://xxx.cn,則請求將成功執(zhí)行。

另外,響應標頭中也攜帶了 Set-Cookie 字段,嘗試對 Cookie 進行修改。如果操作失敗,將會拋出異常。

完整的請求流程圖

fbc88114-5a92-11ee-939d-92fbcf53809c.png

總結

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

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

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

使用預檢請求機制可以有效地防范跨域請求帶來的安全風險,保護用戶數據和隱私。







審核編輯:劉清

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯系本站處理。 舉報投訴
  • HTTP接口
    +關注

    關注

    0

    文章

    21

    瀏覽量

    1792
  • csrf
    +關注

    關注

    0

    文章

    7

    瀏覽量

    2242

原文標題:面試官:post為什么會發(fā)送兩次請求?

文章出處:【微信號:芋道源碼,微信公眾號:芋道源碼】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    TC397 UART接收中斷只會進入兩次,為什么?

    您好,我想詢問有關串口的問題:我在使用串口中斷的時候發(fā)現發(fā)送數據的時候,我的接收中斷只會進入兩次,查看手冊發(fā)現RX FIFO一寫入只能是1 or 2,可是我發(fā)送的數據大于2字節(jié),但是
    發(fā)表于 06-04 09:26

    使用ESP32-S3開發(fā)板http post請求發(fā)送SD卡上的大文件,如何循環(huán)邊讀取文件邊分塊發(fā)送文件呢?

    您和,我準備使用ESP32-S3開發(fā)板http post請求發(fā)送SD卡上的大文件,但是使用esp_http_client_set_post_field的buffer太小,內存不能一
    發(fā)表于 06-06 06:19

    labview上位機串口通信怎么設置點擊一發(fā)送自動重復發(fā)送兩次?。??

    labview上位機給下位機發(fā)送數據,每次發(fā)送位16進制8個但是下位機要接收17個來進行判斷和提取我需要的數值。。但是每次都是連續(xù)按兩次發(fā)送
    發(fā)表于 05-13 14:50

    有辦法使用單個POST請求發(fā)送64 kByte的二進制數據塊嗎?

    嗨,我正在使用SPWF01SA1模塊使用POST請求將數據從我的應用程序發(fā)送到中央服務器。我需要使用單個POST請求傳輸64 kByte的二
    發(fā)表于 03-06 16:07

    為什么lwip+ucosii板子上電會有兩次gratitions arp?

    上電后會發(fā)出倆arp requset,且mac不同,網絡助手發(fā)送udp數據包先針對一個mac,不行的話在廣播請求。這樣會等好久。具體不知道為什么會有
    發(fā)表于 10-10 23:52

    STC單片機兩次下載相同的程序發(fā)現串口發(fā)送的數據不一樣

    今天遇到一個不解的問題,程序中發(fā)送一個固定的字節(jié)數據,我前后兩次下載相同的程序發(fā)現串口發(fā)送的數據前后兩次竟然不同!另外,在KEIL環(huán)境下如何實現在線調試STC單片機程序(不是單純的燒寫
    發(fā)表于 10-30 07:15

    如何使用POST請求從SPIFF向服務器發(fā)送圖像?

    嘗試將圖像(使用 POST 請求發(fā)送到服務器,該服務器將查找圖像中的某些項目并返回包含我需要的信息的 JSON 對象。:我使用手動轉換的 Base64 字符串圖像處理服務器對 API 的 P
    發(fā)表于 02-24 08:35

    如何對Google Cloud IoT Core Pub/Sub的http POST發(fā)送請求?

    我正在 lua 中開發(fā)一個項目,使用 ESPlorer IDE,它需要 ESP8266 通過 http 客戶端 POST 請求將遙測事件發(fā)送到谷歌云物聯網核心,該請求必須具有與以下類似
    發(fā)表于 04-27 07:17

    http請求 get post

    ; importjava.util.List; importjava.util.Map;publicclassHttpRequest{/** * 向指定URL發(fā)送GET方法的請求 * *@paramurl * 發(fā)送
    發(fā)表于 09-27 10:36 ?16次下載

    馬斯克:4新冠病毒檢測 兩次陰性 兩次陽性

    11月13日消息,據外媒報道,特斯拉CEO馬斯克剛剛在社交網絡上表示,今天做了4新冠病毒檢測,檢查結果兩次為陰性兩次為陽性。 馬斯克表示,相同的機器,相同的測試,相同的護士,同樣的抗原檢測
    的頭像 發(fā)表于 11-13 16:29 ?1853次閱讀

    get與post請求一些區(qū)別

    今天再次看到這個問題,我也有了一些新的理解和感觸,臨時回顧了一下 get 與 post請求的一些區(qū)別。
    的頭像 發(fā)表于 09-07 10:00 ?1399次閱讀

    HTTP請求報文:GET和POST的區(qū)別

    GET 和 POST 其實都是 HTTP 的請求方法。除了這 2 個請求方法之外,HTTP 還有 HEAD、PUT、DELETE、TRACE、CONNECT、OPTIONS 這 6 個請求
    發(fā)表于 04-10 10:11 ?2390次閱讀

    所有接口都用post請求的原因

    查看上面的區(qū)別,就會發(fā)post發(fā)送數據量大的請求時優(yōu)勢很顯示,get則更適合獲取靜態(tài)資源、簡單的查詢等接口。 我個人在開發(fā)接口的時候也會注意,將簡單的查詢
    發(fā)表于 08-24 10:06 ?412次閱讀
    所有接口都用<b class='flag-5'>post</b><b class='flag-5'>請求</b>的原因

    python怎么將list輸入兩次

    在Python中,有多種方法可以將一個列表輸入兩次。下面是使用不同的方法來實現此功能的幾個示例: 方法1: 使用循環(huán)將列表復制兩次 這是一種基本的方法,使用循環(huán)遍歷列表并復制其元素兩次。以下是一個
    的頭像 發(fā)表于 11-21 16:17 ?1352次閱讀

    說說TCP三握手的過程?為什么是三而不是兩次、四?

    說說TCP三握手的過程?為什么是三而不是兩次、四? TCP三握手是建立TCP連接的過程,確保數據的可靠傳輸。它是由
    的頭像 發(fā)表于 02-04 11:03 ?683次閱讀