作者:Gakki
我們先來看看 w3school 中對(duì)于 GET 與 POST 的解釋。 GET 與 POST 的區(qū)別
| 分類 | GET | POST | 對(duì)比 |
|---|---|---|---|
| 后退按鈕/刷新 | 無害 | 數(shù)據(jù)會(huì)被重新提交(瀏覽器應(yīng)該告知用戶數(shù)據(jù)會(huì)被重新提交) | 每次都重新提交這無疑會(huì)對(duì)瀏覽器造成壓力,該問題也是作為 web 端性能優(yōu)化的重要方向之一 |
| 書簽 | 可收藏為書簽 | 不可收藏為書簽 | |
| 緩存 | 能被緩存 | 不能緩存 | 緩存可以為瀏覽器減少請(qǐng)求鏈數(shù),web 端性能優(yōu)化的重要方向之一 |
| 編碼類型 | application/x-www-form-urlencoded | application/x-www-form-urlencoded 或 multipart/form-data。為二進(jìn)制數(shù)據(jù)使用多重編碼 | |
| 歷史 | 參數(shù)保留在瀏覽器歷史中 | 參數(shù)不會(huì)保存在瀏覽器歷史中 | 相當(dāng)于緩存,可減少瀏覽器壓力 |
| 對(duì)數(shù)據(jù)長度的限制 | 當(dāng)發(fā)送數(shù)據(jù)時(shí),GET 方法向 URL 添加數(shù)據(jù);URL 的長度是受限制的(URL 的最大長度是 2048 個(gè)字符) | 無限制 | HTTP 協(xié)議沒有 Body 和 URL 的長度限制,對(duì) URL 限制的大多是瀏覽器和服務(wù)器的原因;服務(wù)器是因?yàn)樘幚黹L URL 要消耗比較多的資源,為了性能和安全(防止惡意構(gòu)造長 URL 來攻擊)考慮,會(huì)給 URL 長度加限制 |
| 對(duì)數(shù)據(jù)類型的限制 | 只允許 ASCII 字符 | 沒有限制。也允許二進(jìn)制數(shù)據(jù) | POST 選擇更多 |
| 安全性 | 與 POST 相比,GET 的安全性較差,因?yàn)樗l(fā)送的數(shù)據(jù)是 URL 的一部分 | POST 比 GET 更安全,因?yàn)閰?shù)不會(huì)被保存在瀏覽器歷史或 web 服務(wù)器日志中 | 從傳輸?shù)慕嵌葋碚f,他們都是不安全的,因?yàn)?HTTP 在網(wǎng)絡(luò)上是明文傳輸?shù)?,瀏覽器F12下什么都一目了然,或者抓個(gè)包,就能完整地獲取數(shù)據(jù)報(bào)文 ;要想安全傳輸,Encode(轉(zhuǎn)碼)當(dāng)然對(duì)于懂的人來說也不安全; 比較安全的只有加密,也就是 HTTPS |
| 可見性 | 數(shù)據(jù)在 URL 中對(duì)所有人都是可見的 | 數(shù)據(jù)不會(huì)顯示在 URL 中 |
- 注:上述區(qū)別在大部分瀏覽器上是存在的,因?yàn)檫@些瀏覽器實(shí)現(xiàn)了 HTTP 標(biāo)準(zhǔn)
- 所以,從上述標(biāo)準(zhǔn)來看,GET 與 POST 的區(qū)別在于:
- GET 用于獲取信息,是無副作用的,是冪等的且可緩存
- POST 用于修改服務(wù)器上的數(shù)據(jù),有副作用,非冪等,不可緩存
- 注,冪等的概念:如果一個(gè)操作沒有副作用,或者多次操作對(duì)資源產(chǎn)生的副作用相同,我們就說這個(gè)操作是冪等的
1. GET 與 POST
-
一般在面試的時(shí)候,面試官都會(huì)問道這個(gè)問題,一般這樣回答:
- GET 在瀏覽器回退時(shí)是無害的,而 POST 會(huì)再次提交請(qǐng)求
- GET 參數(shù)通過 URL 傳遞,POST 放在 body 中
- GET 比 POST 更不安全,因?yàn)?GET 請(qǐng)求的時(shí)候?qū)?shù)直接暴露在 URL 上,所以最好不要用來傳遞敏感信息
- 對(duì)比參數(shù)的數(shù)據(jù)類型,GET 只接受 ASCII 字符,而 POST 沒有限制
- GET 請(qǐng)求只能進(jìn)行 URL 編碼,而 POST 支持多種多種編碼方式
- GET請(qǐng)求參數(shù)會(huì)被完整保留在瀏覽器歷史記錄里,而POST中的參數(shù)不會(huì)被保留。
- GET 常用于獲取數(shù)據(jù),POST 用于提交數(shù)據(jù)
但其實(shí),GET 與 POST 并沒有實(shí)質(zhì)的區(qū)別
POST 與 GET 是什么?它們都是 HTTP 協(xié)議中的兩種發(fā)送請(qǐng)求的方法
那什么是 HTTP 了? HTTP 超文本傳輸協(xié)議(Hypertext Transfer Protocol,縮寫 HTTP)旨在啟用客戶端和服務(wù)器之間的通信。HTTP 充當(dāng)客戶端和服務(wù)器之間的請(qǐng)求-響應(yīng)協(xié)議。如:客戶端(瀏覽器)向服務(wù)器發(fā)送 HTTP 請(qǐng)求;然后服務(wù)器將響應(yīng)返回客戶端。響應(yīng)包含有關(guān)請(qǐng)求的狀態(tài)信息,也可能包含所請(qǐng)求的內(nèi)容。HTTP 的底層是 TCP/IP ,因此 GET 和 POST 的底層也是 TCP/IP 。換句話說,GET 和 POST 都是 TCP 鏈接,你可以給 GET 的 request body 中傳值,也可以給 POST 加上 URL 參數(shù),只是看服務(wù)器那邊是否接受處理。導(dǎo)致 GET 與 POST 在應(yīng)用中區(qū)別的是由于 HTTP 的規(guī)定和瀏覽器/服務(wù)器的限制
TCP 是用來傳輸數(shù)據(jù)的,是可靠傳輸。HTTP 規(guī)定了幾種常用的請(qǐng)求方法,最常用的POST 、 GET ,HTTP 規(guī)定在 GET 請(qǐng)求的時(shí)候,要求把傳送的數(shù)據(jù)放在 URL 中,POST 請(qǐng)求的時(shí)候,放在 body 中。但是,你也可以在 GET 請(qǐng)求的時(shí)候,在 body 中放參數(shù),POST 請(qǐng)求的時(shí)候,在 URL 放數(shù)據(jù)。HTTP 只是一個(gè)準(zhǔn)則,主要的還是需要看 TCP
關(guān)于 w3school 所說的參數(shù)大小的限制是在哪體現(xiàn)的了?理論上,你可以在 URL 中無限制的加參數(shù),但是瀏覽器與服務(wù)器會(huì)去限制單次傳輸?shù)膮?shù)來控制風(fēng)險(xiǎn),數(shù)據(jù)量太大會(huì)對(duì)瀏覽器與服務(wù)器造成很大的風(fēng)險(xiǎn)。因此,在萬維網(wǎng)(WWW)中,大多數(shù)的瀏覽器通常都會(huì)限制 URL 長度在 2K 個(gè)字節(jié),而大多數(shù)服務(wù)器最多也只處理 64K 大小的 URL ,超過的部分都不會(huì)去處理。但如果用 GET 請(qǐng)求的時(shí)候,在 request body 中放了數(shù)據(jù),不同的服務(wù)器處理的方式也不同,有的會(huì)處理,有的服務(wù)器會(huì)直接忽略。因此,雖然 GET 可以在 body 放參數(shù),但也不能保證服務(wù)器會(huì)接收數(shù)據(jù)
因此,GET 與 POST 本質(zhì)上都是 TCP 鏈接,沒有什么差別。但是由于 HTTP 的規(guī)定 與 瀏覽器/服務(wù)器 的限制,導(dǎo)致 GET 與 POST 在應(yīng)用中存在區(qū)別
2. GET 與 POST 實(shí)質(zhì)的區(qū)別
- GET 產(chǎn)生一個(gè) TCP 數(shù)據(jù)包;POST 產(chǎn)生兩個(gè) TCP 數(shù)據(jù)包
- 對(duì)于 GET 請(qǐng)求,瀏覽器會(huì)把 header 和 data 一起發(fā)送出去,服務(wù)器會(huì)響應(yīng)數(shù)據(jù)
- 而對(duì)于 POST 請(qǐng)求,瀏覽器會(huì)先將 header ,服務(wù)器響應(yīng) 100 狀態(tài)碼,接著瀏覽器再將 data 數(shù)據(jù)發(fā)送出去,服務(wù)器響應(yīng)數(shù)據(jù)
- 總結(jié),GET 只需要發(fā)送一次包,而 POST 會(huì)發(fā)送給兩次包。因?yàn)?POST 需要發(fā)送兩次的原因,導(dǎo)致會(huì)比 GET 更會(huì)費(fèi)時(shí)間。但是在網(wǎng)絡(luò)環(huán)境比較好的情況下,發(fā)一次包的時(shí)間和發(fā)兩次包的時(shí)間基本沒有差別;而在網(wǎng)絡(luò)環(huán)境比較差的情況下,兩次包的 TCP 在驗(yàn)證數(shù)據(jù)包的完整性上有著非常大的優(yōu)勢(shì)。然后就是并不是所有的瀏覽器都會(huì)在 POST 中發(fā)送兩次包,F(xiàn)ireFox 、Chrome 只會(huì)發(fā)送一次;header 和 body 分開發(fā)送是部分瀏覽器或框架的請(qǐng)求方法,不屬于 POST 必然行為。
3. 雜談
POST 方法比 GET 方法安全?
- 按照網(wǎng)上大多數(shù)博文的回答,POST 都比 GET 安全,因?yàn)?POST 是將參數(shù)放在 body 中傳輸?shù)?,?URL 中是不可見的。但是,從傳輸?shù)慕嵌葋碚f,它們都是不安全的,因?yàn)?HTTP 在網(wǎng)絡(luò)上是明文傳輸,只要在網(wǎng)絡(luò)節(jié)點(diǎn)上進(jìn)行抓包,就可以把數(shù)據(jù)完整的獲取下來。要想安全傳輸,最好使用加密,也就是 HTTPS
- 關(guān)于 GET 方法的長度限制?
- 在 w3school 中,我們看到 URL 的長度是受限制的。但 HTTP 協(xié)議沒有對(duì) body 與 URL 的長度設(shè)置限制,對(duì) URL 設(shè)置限制大多數(shù)都是瀏覽器和服務(wù)器的原因。當(dāng)服務(wù)器處理較長的 URL 的時(shí)候,需要消耗比較多的資源,為了性能和安全考慮(防止惡意構(gòu)置長 URL 來攻擊服務(wù)器),會(huì)給 URL 長度加限制
為什么body更安全?
- 與 POST 相比,GET 的安全性較差,因?yàn)樗l(fā)送的數(shù)據(jù)是 URL 的一部分。在發(fā)送密碼或其他敏感信息時(shí)絕不要使用 GET
- POST 比 GET 更安全,因?yàn)閰?shù)不會(huì)被保存在瀏覽器歷史或 web 服務(wù)器日志中
- 從傳輸?shù)慕嵌葋碚f,他們都是不安全的,因?yàn)?HTTP 在網(wǎng)絡(luò)上是明文傳輸?shù)模瑸g覽器F12下什么都一目了然,或者抓個(gè)包,就能完整地獲取數(shù)據(jù)報(bào)文 ;要想安全傳輸, 比較安全的只有加密,也就是 HTTPS
get長度和瀏覽器有關(guān)?
- HTTP 協(xié)議沒有 Body 和 URL 的長度限制,對(duì) URL 限制的大多是瀏覽器和服務(wù)器的原因;服務(wù)器是因?yàn)樘幚黹L URL 要消耗比較多的資源,為了性能和安全(防止惡意構(gòu)造長 URL 來攻擊)考慮,會(huì)給 URL 長度加限制