<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ā)送兩次請求?

          共 3426字,需瀏覽 7分鐘

           ·

          2024-08-05 08:45

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

          瀏覽 157
          1點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

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

          手機(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>
                  久久无码性爱视频 | 天天干天天碰 | 欧美蜜桃亚洲 | 大香蕉久久久久久久久久久 | 色黄视频免费看欧美 |