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

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

          共 5367字,需瀏覽 11分鐘

           ·

          2021-08-23 08:56

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

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


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

          引言

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

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

          標準答案

          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。為二進制數(shù)據(jù)使用多重編碼。
          歷史 參數(shù)保留在瀏覽器歷史中。 參數(shù)不會保存在瀏覽器歷史中。
          對數(shù)據(jù)長度的限制 是的。當(dāng)發(fā)送數(shù)據(jù)時,GET 方法向 URL 添加數(shù)據(jù);URL 的長度是受限制的(URL 的最大長度是 2048 個字符)。 無限制。
          對數(shù)據(jù)類型的限制 只允許 ASCII 字符。 沒有限制。也允許二進制數(shù)據(jù)。
          安全性 與 POST 相比,GET 的安全性較差,因為所發(fā)送的數(shù)據(jù)是 URL 的一部分。在發(fā)送密碼或其他敏感信息時絕不要使用 GET ! POST 比 GET 更安全,因為參數(shù)不會被保存在瀏覽器歷史或 web 服務(wù)器日志中。
          可見性 數(shù)據(jù)在 URL 中對所有人都是可見的。 數(shù)據(jù)不會顯示在 URL 中。

          上面是 w3school 給出的標準答案

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

          下面讓我們一步步走進 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ù)完整性等傳輸細節(jié),這些底層的具體傳輸工作是由 TCP/IP 協(xié)議負責(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ù)器端的資源進行操作,例如查詢、添加、刪除等,但具體執(zhí)行哪種操作喃?

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

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

          進階:常見問題及解答

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

          在 HTTP 協(xié)議里,所謂的“安全”是指請求方法不會對服務(wù)器上的資源進行修改,“破壞”服務(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ù)器是否會接受這個實體這種情況進行優(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)或一條錯誤碼來進行響應(yīng)。服務(wù)器永遠也不應(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ù)「交流」自動加入前端三分鐘進階群,每日一道編程算法面試題(含解答),助力你成為更優(yōu)秀的前端開發(fā)!
          》》面試官也在看的前端面試資料《《
          “在看和轉(zhuǎn)發(fā)”就是最大的支持
          瀏覽 39
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

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

          手機掃一掃分享

          分享
          舉報
          <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>
                  美女啪啪啪免费网站 | 97超碰人人 | 精品久久免费一区二区三区 | 色欲综合一区二区 | 欧美性爱日逼 |