1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        你真的了解 GET 和 POST 嗎,它們的區(qū)別是什么?

        共 5367字,需瀏覽 11分鐘

         ·

        2021-08-23 08:56

        點擊上方 三分鐘學(xué)前端,關(guān)注公眾號

        回復(fù)交流,加入前端編程面試算法每日一題群


        面試官也在看的前端面試資料

        引言

        本文從以下幾個方面走進(jìn) GET 與 POST 的區(qū)別:

        • w3school 給出的標(biāo)準(zhǔn)答案
        • 從 HTTP 是什么開始,深入 GET 與 POST 請求方法,及兩者的本質(zhì)區(qū)別
        • 常見的 GET 與 POST 問題與誤解
          • POST 方法比 GET 方法安全?
          • POST 方法會產(chǎn)生兩個 TCP 數(shù)據(jù)包?

        標(biāo)準(zhǔn)答案

        GET 與 POST 是 HTTP 請求中最常用的兩種方法,GET 與 POST 的區(qū)別也是老生常談的問題了,信手拈來


        GET POST
        后退按鈕/刷新 無害 數(shù)據(jù)會被重新提交(瀏覽器應(yīng)該告知用戶數(shù)據(jù)會被重新提交)。
        書簽 可收藏為書簽 不可收藏為書簽
        緩存 能被緩存 不能緩存
        編碼類型 application/x-www-form-urlencoded application/x-www-form-urlencoded 或 multipart/form-data。為二進(jìn)制數(shù)據(jù)使用多重編碼。
        歷史 參數(shù)保留在瀏覽器歷史中。 參數(shù)不會保存在瀏覽器歷史中。
        對數(shù)據(jù)長度的限制 是的。當(dāng)發(fā)送數(shù)據(jù)時,GET 方法向 URL 添加數(shù)據(jù);URL 的長度是受限制的(URL 的最大長度是 2048 個字符)。 無限制。
        對數(shù)據(jù)類型的限制 只允許 ASCII 字符。 沒有限制。也允許二進(jìn)制數(shù)據(jù)。
        安全性 與 POST 相比,GET 的安全性較差,因為所發(fā)送的數(shù)據(jù)是 URL 的一部分。在發(fā)送密碼或其他敏感信息時絕不要使用 GET ! POST 比 GET 更安全,因為參數(shù)不會被保存在瀏覽器歷史或 web 服務(wù)器日志中。
        可見性 數(shù)據(jù)在 URL 中對所有人都是可見的。 數(shù)據(jù)不會顯示在 URL 中。

        上面是 w3school 給出的標(biāo)準(zhǔn)答案

        但你真的理解它嗎?在我們學(xué)習(xí)了那么多 HTTP 知識后,僅僅回答這些就夠了嗎?GET 與 POST 都是 HTTP 的請求方法,如何理解請求方法?本質(zhì)區(qū)別又是什么?

        下面讓我們一步步走進(jìn) GET 與 POST 方法,以及兩者的本質(zhì)區(qū)別

        深入 GET 與 POST 請求方法

        1. HTTP 是什么?

        HTTP (HyperText Transfer Protocol)是建立在 TCP 上的應(yīng)用層協(xié)議,超文本傳輸協(xié)議。其中:

        • 超文本:圖片、音頻、視頻、甚至是壓縮包等
        • 傳輸:兩點之間數(shù)據(jù)的雙向傳送
        • 協(xié)議:一種行為約定和規(guī)范

        所以,HTTP 協(xié)議用更通俗易懂的話描述就是 一個在計算機世界里專門在兩點之間傳輸文字、圖片、音頻、視頻等超文本數(shù)據(jù)的約定和規(guī)范

        雖說 HTTP 協(xié)議是“傳輸協(xié)議”,但它不關(guān)心尋址、路由、數(shù)據(jù)完整性等傳輸細(xì)節(jié),這些底層的具體傳輸工作是由 TCP/IP 協(xié)議負(fù)責(zé),例如 IP 協(xié)議實現(xiàn)尋址和路由、TCP 協(xié)議實現(xiàn)可靠數(shù)據(jù)傳輸,另外還有 DNS 協(xié)議實現(xiàn)域名查找、SSL/TLS 協(xié)議實現(xiàn)安全通信等

        那 HTTP 協(xié)議主要干嘛喃?

        2. HTTP 報文

        HTTP 協(xié)議的核心部分就是它定義的傳輸報文的格式,例如報文的組成、解析規(guī)則等,以便于在 TCP/IP 上實現(xiàn)更多樣靈活的功能,如緩存控制、數(shù)據(jù)編碼、內(nèi)容協(xié)議等

        HTTP 報文分為四部分:

        • 起始行:在請求報文中是請求行,在響應(yīng)報文中是狀態(tài)行(表示服務(wù)器的響應(yīng)狀態(tài))
        • 頭部:header
        • 空行:在 header 與 body 之間其實是有個 “空行” 的
        • 實體:我們通常說的 body

        注意:此報文中最后是一個空白行結(jié)束,沒有 body(GET 請求一般都沒有 body)

        其中,請求方法就規(guī)定在起始行中:

        • 請求行:GET /uri HTTP/1.1,包含請求方法 GET 或 POST 等
        • 狀態(tài)行:HTTP/1.1 200 OK,僅僅包含服務(wù)器的響應(yīng)狀態(tài),不包含請求方法

        請求方法

        客戶端發(fā)起 HTTP 請求,服務(wù)器響應(yīng)客戶端請求,客戶端可以對服務(wù)器端的資源進(jìn)行操作,例如查詢、添加、刪除等,但具體執(zhí)行哪種操作喃?

        這就是請求方法存在的意義,它規(guī)定了客戶端的某種操作指令,用來告訴服務(wù)器端我需要進(jìn)行哪種操作,常見的請求方法有:

        • GET :獲取資源,常用于讀取或下載資源
        • HEAD :請求一個與 GET 請求的響應(yīng)相同的響應(yīng),只返回請求頭,沒有響應(yīng)體,多數(shù)由 JavaScript 發(fā)起
        • POST :用于將實體(body)提交到指定的資源,通常導(dǎo)致狀態(tài)或服務(wù)器上的副作用的更改
        • PUT :用請求有效載荷替換目標(biāo)資源的所有當(dāng)前表示。
        • DELETE :刪除指定的資源。
        • CONNECT :建立一個到由目標(biāo)資源標(biāo)識的服務(wù)器的隧道,多用于 HTTPS 和 WebSocket 。
        • OPTIONS :預(yù)檢,用于描述目標(biāo)資源的通信選項。通過該請求來知道服務(wù)端是否允許跨域請求。
        • TRACE :沿著到目標(biāo)資源的路徑執(zhí)行一個消息環(huán)回測試,多數(shù)線上服務(wù)都不支持
        • PATCH :用于對資源應(yīng)用部分修改。

        GET 請求方法應(yīng)該是 HTTP 所有請求方法中最開始出現(xiàn)的了,它表示從服務(wù)器獲取資源

        POST 請求方法是 HTTP 所有協(xié)議中除 GET 之外最常使用的請求方法了,它表示向指定的服務(wù)器資源提交數(shù)據(jù),提交數(shù)據(jù)存放在 HTTP 報文中的 body 中,通常導(dǎo)致狀態(tài)或服務(wù)器上的副作用的更改

        3. GET 與 POST 請求方法的本質(zhì)區(qū)別

        綜上所述,總結(jié)一下,GET 與 POST 的本質(zhì)區(qū)別有兩點:

        • 請求行不同:
          • GET:GET /uri HTTP/1.1
          • POST:POST /uri HTTP/1.1
        • 對服務(wù)器資源的操作不同:
          • GET:表示從服務(wù)器獲取資源
          • POST:向指定的服務(wù)器資源提交數(shù)據(jù)(通常導(dǎo)致狀態(tài)或服務(wù)器上的副作用的更改)

        進(jìn)階:常見問題及解答

        1. POST 方法比 GET 方法安全?

        在 HTTP 協(xié)議里,所謂的“安全”是指請求方法不會對服務(wù)器上的資源進(jìn)行修改,“破壞”服務(wù)器上的資源

        按照這種定義,GET 請求方法是安全的,它對服務(wù)器資源執(zhí)行的僅僅是只讀操作,也是冪等的

        冪等指多次執(zhí)行相同的操作,結(jié)果也都是相同的,即多次“冪”后結(jié)果“相等”

        POST 請求方法是不安全的,它會修改服務(wù)器上的資源,在 RFC 里的語義,POST 是指“新增或提交數(shù)據(jù)”,多次提交數(shù)據(jù)會創(chuàng)建多個資源,所以不是冪等的

        總結(jié):

        • GET:安全,冪等
        • POST:不安全,不冪等

        對于傳輸來說,GET 和 POST 報文在傳輸上都是不安全的,因為 HTTP 在網(wǎng)絡(luò)上是明文傳輸?shù)模胍踩珎鬏斁偷眉用?,也就?HTTPS

        2. POST 方法會產(chǎn)生兩個 TCP 數(shù)據(jù)包?

        這個就神奇了,在部分文章中提到,POST 請求方法會將 header 和 body 分開發(fā)送,先發(fā)送 header,服務(wù)端返回 100 狀態(tài)碼再發(fā)送 body ?????????

        HTTP 協(xié)議中沒有明確說明 POST 會產(chǎn)生兩個 TCP 數(shù)據(jù)包,而且實際測試(Chrome、Firefox)發(fā)現(xiàn),header 和 body 不會分開發(fā)送。

        但為什么有些作者會這樣寫喃?我查找了相關(guān)資料,終于發(fā)現(xiàn),真有這種情況,原文在這里:

        In search of performance - how we shaved 200ms off every POST request

        https://gocardless.com/blog/in-search-of-performance-how-we-shaved-200ms-off-every-post-request/

        主要內(nèi)容是作者發(fā)現(xiàn) POST 比 GET 多 200ms,然后深入研究,發(fā)現(xiàn) ruby 的 net::HTTP 庫,會將一個 http 請求拆分,先發(fā)送 header 部分。另外,由于沒有設(shè)置 TCP_NODELY ,所以第一個包之后要等待 ack ,才發(fā)下一個包,導(dǎo)致了一個請求有 200ms 的延遲。

        另外,關(guān)于 HTTP 100  Continue:

        100 Continue的目的是對HTTP客戶端應(yīng)用程序有一個實體的主體部分要發(fā)送服務(wù)器,但希望在發(fā)送之前查看一下服務(wù)器是否會接受這個實體這種情況進(jìn)行優(yōu)化

        ----《HTTP權(quán)威指南》

        客戶端:

        如果客戶端在向服務(wù)器發(fā)送一個實體,并愿意在發(fā)送實體之前等待100 Continue響應(yīng),那么客戶端就要發(fā)送一個攜帶了值為100 Continue的Expect請求首部。如果客戶端沒有發(fā)送實體,就不應(yīng)該發(fā)送100 Continue Expect首部,因為這樣會使服務(wù)器誤以為客戶端要發(fā)送一個實體

        服務(wù)器端:

        如果服務(wù)器收到一條帶有值為100 Continue的Expect首部的請求,它會用100 Continue響應(yīng)或一條錯誤碼來進(jìn)行響應(yīng)。服務(wù)器永遠(yuǎn)也不應(yīng)該向沒有發(fā)送100 Continue期望的客戶端發(fā)送100 Continue狀態(tài)碼。

        如果服務(wù)器在有機會發(fā)送100 Continue響應(yīng)之前就收到了部分(或者全部)的實體,說明服務(wù)器已經(jīng)打算繼續(xù)發(fā)送數(shù)據(jù)了,這樣服務(wù)器就不需要發(fā)送這個狀態(tài)碼了,但是服務(wù)器完成請求之后,還是應(yīng)該為請求發(fā)送一個最終狀態(tài)碼

        也就是說,沒收到客戶端的 100 Continue 就不會有響應(yīng)

        總結(jié)

        因此,大多數(shù)框架都是盡量在一個 TCP 包里面把 HTTP 請求發(fā)出去的,但是也確實存在先發(fā) HTTP 頭,然后發(fā) body 的框架。但是具體發(fā)多少個TCP包,這個 不是 HTTP 協(xié)議的事情是操作系統(tǒng) TCP 協(xié)議棧與代碼的問題,跟 HTTP 沒關(guān)系

        最后

        歡迎關(guān)注「三分鐘學(xué)前端」,回復(fù)「交流」自動加入前端三分鐘進(jìn)階群,每日一道編程算法面試題(含解答),助力你成為更優(yōu)秀的前端開發(fā)!
        》》面試官也在看的前端面試資料《《
        “在看和轉(zhuǎn)發(fā)”就是最大的支持
        瀏覽 39
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

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

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            亚洲一区二区三区蜜桃 | 91综合视频 | 亚洲第一网站 | 国产精品15p | 青青操原| 一级a一级a免费观看视频Al明星 | 日B网址 先锋AV啪啪资源站 | 黄片在线浏览 | 亚洲视频免费完整版在线播放 | 狠狠躁夜夜躁av毛片 |