1. 面試官:post為什么會發(fā)送兩次請求?

        共 3426字,需瀏覽 7分鐘

         ·

        2024-08-19 09:10

        之前有人跟我們說,出去面試的時候,有時候會遇到一些讓人頭疼的問題,比如有一次去字節(jié)面試,面試官就問了一個讓他很奇怪的問題:“為啥POST請求有時候會發(fā)送兩次呢?”這個問題聽起來挺玄乎的,但其實用大白話來說,原因還挺簡單的。咱們這就來聊聊這個事兒。
        首先,得明白啥是POST請求。POST請求就是咱們在網(wǎng)上干點啥事兒,比如提交個表單、上傳個文件啥的,得跟服務(wù)器說:“嘿,我這兒有點東西,你給我處理一下?!边@時候,瀏覽器就會發(fā)個POST請求給服務(wù)器。
        那么,為啥有時候會發(fā)兩次呢?這其實跟瀏覽器的“預(yù)檢”機制有關(guān)系。簡單來說,就是瀏覽器在正式發(fā)請求之前,會先問問服務(wù)器:“嘿,我要發(fā)請求了,你準(zhǔn)備好了嗎?能接收嗎?”這個過程就叫做“預(yù)檢請求”,也叫OPTIONS請求。
        為啥要有這個預(yù)檢呢?因為有時候咱們發(fā)的請求可能比較復(fù)雜,比如請求頭里面帶了點特殊的東西,或者請求方法是PUT、DELETE這種不常用的。這時候,瀏覽器就會有點擔(dān)心,怕服務(wù)器不理解或者不接受這個請求,所以就先發(fā)個簡單的OPTIONS請求去問問。
        如果服務(wù)器說:“沒問題,你來吧!”那瀏覽器就會再發(fā)一次正式的POST請求。所以,咱們就看到了兩次請求:一次是預(yù)檢的OPTIONS請求,一次是正式的POST請求。
        那么,舉個實際的例子來說明一下。假設(shè)你正在開發(fā)一個網(wǎng)頁應(yīng)用,其中有一個功能是讓用戶能夠上傳圖片。當(dāng)用戶選擇了一張圖片并點擊上傳按鈕時,瀏覽器就會發(fā)送一個POST請求到服務(wù)器,以便將圖片上傳到服務(wù)器上。
        但是,如果這個請求中包含了一些特殊的請求頭,比如自定義的X-Requested-With頭,或者請求的內(nèi)容類型(Content-Type)不是常見的application/x-www-form-urlencodedmultipart/form-datatext/plain,那么瀏覽器就會先發(fā)送一個OPTIONS請求進(jìn)行預(yù)檢。
        這個OPTIONS請求會詢問服務(wù)器是否接受這種類型的請求。如果服務(wù)器響應(yīng)說可以接受,那么瀏覽器才會繼續(xù)發(fā)送正式的POST請求,將圖片上傳到服務(wù)器上。
        預(yù)檢請求和正式請求之間有一些明顯的區(qū)別。首先,它們的目的不同。預(yù)檢請求的目的是詢問服務(wù)器是否接受某種類型的請求,而正式請求則是實際執(zhí)行某種操作,比如上傳文件、提交表單等。其次,它們的請求方法不同。預(yù)檢請求總是使用OPTIONS方法,而正式請求則可以使用GET、POST、PUT、DELETE等方法。最后,它們的請求頭和請求體也可能不同。預(yù)檢請求通常只包含一些基本的請求頭,而正式請求則可能包含更多的請求頭和請求體數(shù)據(jù)。
        所以,先總結(jié)一下,POST請求有時候會發(fā)送兩次,是因為瀏覽器為了保險起見,先發(fā)個預(yù)檢請求去問問服務(wù)器:“我能發(fā)這個請求嗎?”得到允許后,再發(fā)正式的請求。這樣,就能確保咱們的請求能夠順利到達(dá)服務(wù)器,并得到正確的處理了。
        好了,現(xiàn)在大家明白了吧,以后面試遇到這個問題就可以很好的回答清楚了,說白了不是發(fā)送兩次post請求,而是在一些特殊的情況下,如果post請求要帶一些特殊的請求頭,平時不太常見,瀏覽器就會發(fā)擔(dān)心服務(wù)端沒法接收和處理,那如果服務(wù)端沒法處理,自己何必還發(fā)送post請求攜帶大量的表單數(shù)據(jù)、文件數(shù)據(jù)、圖片數(shù)據(jù)過去呢?這不是吃飽了沒事干么,對吧!
        所以此時才會先發(fā)個options預(yù)檢請求過去,帶一些請求頭,問一下服務(wù)端后面能不能處理正式的請求。另外的話,對于發(fā)options預(yù)檢請求的情況還有一種比較特殊的,就是同源策略下的跨域訪問,這個也是有可能會提前發(fā)options預(yù)檢請求的。
        瀏覽器的同源策略,簡單來說,就是瀏覽器為了安全起見,設(shè)置的一個規(guī)矩。這個規(guī)矩規(guī)定,來自不同源的網(wǎng)頁之間不能直接進(jìn)行交互。這里的“源”指的是協(xié)議(比如http或https)、域名(比如www.example.com)和端口號(比如80或443)這三者的組合。只要這三者中有任何一個不同,就認(rèn)為是不同的源。
        那不同的源肯定不能互相瞎請求啊,比如說瀏覽器請求服務(wù)器A返回了一個網(wǎng)頁,結(jié)果這個服務(wù)器A跑的A系統(tǒng)的網(wǎng)頁里,有一個請求要去請求服務(wù)器B上部署的B系統(tǒng),那這種就很奇怪了,對瀏覽器來說你們是兩個服務(wù)器,也就是兩個不同的系統(tǒng),干什么要互相瞎訪問,有沒有可能A系統(tǒng)是一個涉灰系統(tǒng)在搞破壞,盜取數(shù)據(jù),對不對?
        舉個日常的例子,就像你有兩個家,一個在北京,一個在上海。雖然都是你的家,但因為地理位置不同(就像協(xié)議、域名、端口號不同),所以你不能直接從北京的家跑到上海的家去拿東西,除非你走特殊通道(就像跨域資源共享CORS)。
        那CORS的話,全稱是跨域資源共享(Cross-Origin Resource Sharing),是瀏覽器和服務(wù)器之間的一種約定,用來解決跨域請求的問題。簡單來說,CORS就是一種機制,讓服務(wù)器告訴瀏覽器:“嘿,這個網(wǎng)頁雖然來自不同的源,但它是安全的,你可以讓它訪問我的資源?!?/span>
        就是說服務(wù)器A的網(wǎng)頁里的JS代碼去請求服務(wù)器B了,那就是跨域了,那跨域發(fā)起的請求就是CORS請求了。
        那瀏覽器發(fā)跨域請求的時候,會不回發(fā)options預(yù)檢請求呢?其實也是會的,因為當(dāng)瀏覽器發(fā)起跨域請求時,并不是所有的請求都會直接發(fā)送。有時候,瀏覽器也是會先發(fā)出一個OPTIONS請求,這個請求就像是瀏覽器在問服務(wù)器:“嘿,我這兒有一個網(wǎng)頁想發(fā)個請求到你的地盤,但是網(wǎng)頁和你的話,咱倆不是同一個源的,你得先告訴我,你同不同意?”這個過程就叫做跨域請求之前的預(yù)檢請求。
        那么,跨域請求的時候,什么情況下會發(fā)出OPTIONS預(yù)檢請求呢?主要有以下幾種情況:
        1、請求方法不是GET、HEAD、POST:因為GET、HEAD、POST這三種方法被認(rèn)為是“簡單”的,通常不會對服務(wù)器造成太大影響,所以瀏覽器會直接發(fā)送請求。但如果是PUT、DELETE等方法,瀏覽器就會先發(fā)個OPTIONS請求問問,就怕有人要搞破壞。
        對于GET、HEAD、POST這種簡單請求,瀏覽器是沒有預(yù)檢請求的,他會直接發(fā)送請求到服務(wù)器,并在請求頭中包含一個Origin字段,表明這個請求的來源。服務(wù)器收到請求后,會根據(jù)請求頭中的Origin字段來決定是否允許這個跨域請求。如果允許,服務(wù)器會在響應(yīng)頭中包含Access-Control-Allow-Origin字段,并返回相應(yīng)的資源。
        但是大部分情況下,很多后端系統(tǒng)如果用的是MVC框架的話,都會默認(rèn)禁止CORS跨域請求,所以這個時候如果你發(fā)現(xiàn)后端系統(tǒng)異常了,配置一下MVC框架,打開CORS跨域請求支持就可以了,那就可以處理跨域請求了。
        2、請求頭包含了自定義字段:比如你在請求頭里加了個X-Token,瀏覽器就會覺得:“咦,這個請求頭看起來不簡單,我得先問問服務(wù)器同不同意?!?/span>
        3、Content-Type不是常見的三種類型:常見的Content-Type有application/x-www-form-urlencodedmultipart/form-datatext/plain。如果你用了其他類型,比如application/json,瀏覽器也會先發(fā)個OPTIONS請求。
        再總結(jié)一下,當(dāng)瀏覽器覺得一個跨域請求“不簡單”時,就會先發(fā)個OPTIONS請求去預(yù)檢一下,看看服務(wù)器同不同意。如果服務(wù)器同意了,瀏覽器才會繼續(xù)發(fā)送正式的請求。這就像你去別人家做客,如果不是很熟,你可能會先打個電話問問對方方不方便,得到同意后再去。
        好了,今天咱們從一個面試題問post為什么發(fā)兩次請求開始引入,用大白話重點聊了聊瀏覽器的options預(yù)檢請求問題,并且舉了一些例子,尤其是講了一些同源策略、跨域請求、預(yù)檢請求之間的關(guān)系,相信大家也學(xué)到了不少東西,以后面試遇到一定要加油!

        瀏覽 311
        1點贊
        評論
        收藏
        分享

        手機掃一掃分享

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

        手機掃一掃分享

        分享
        舉報
          
          

            1. 久草视频2| 国产乱码一区二区三区 | 另类小说亚洲区欧美动图无码第页 | 超碰大香蕉 | 国内精品一级毛片国产99 |