我們會(huì)經(jīng)??吹接腥藛枺篽ttp協(xié)議中GET請(qǐng)求和POST請(qǐng)求有什么區(qū)別~?
這個(gè)問題看似很簡(jiǎn)單,但是不同程度的人會(huì)回答出不同的結(jié)果。在公司的面試中,也會(huì)經(jīng)常的問及類似這樣的問題,看似很簡(jiǎn)單,但是不同層次的人會(huì)回答出不同的結(jié)果。那么我們今天就來(lái)聊聊HTTP協(xié)議中GET與POST的真正區(qū)別。
我們還是要用一句簡(jiǎn)練的話來(lái)回答GET和POST的區(qū)別:
提及GET和POST的區(qū)別,一定要確定基于什么前提。在不同的前提下有不同的答案。
這么簡(jiǎn)單的GET和POST背后有什么神秘的面紗呢?我們今天依然用鄧哥的例子來(lái)講給大家~
鄧哥家住在吃雞村,鄧嫂家住在農(nóng)藥屯。鄧哥到鄧嫂家可以有很多種選擇,走著去、駕車去、坐火車去等等。鄧哥通常選擇駕車過去。
這里吃雞村和農(nóng)藥屯就相當(dāng)于是互聯(lián)網(wǎng)中的兩臺(tái)計(jì)算機(jī),鄧哥和鄧嫂相當(dāng)于是這兩臺(tái)計(jì)算機(jī)中的兩個(gè)程序,這兩個(gè)程序之間想要通信可以有很多種協(xié)議,就好比有很多種交通方式可以到達(dá)。我們假設(shè)駕車這種方式就是網(wǎng)絡(luò)中的HTTP協(xié)議。
鄧哥家有兩輛車,一輛轎車,一輛箱式貨車。
兩種車就好比是HTTP協(xié)議中的兩種方式,我們假設(shè)轎車是GET請(qǐng)求方式,箱式貨車是POST請(qǐng)求方式。
有一天鄧哥想接鄧嫂來(lái)吃雞村玩,鄧哥準(zhǔn)備開箱式貨車去接鄧嫂。
鄧哥要去接鄧嫂,就好比程序A要向程序B發(fā)出一個(gè)請(qǐng)求。從原理上說(shuō),無(wú)論是轎車還是貨車都是車,都能夠把人接回來(lái)。所以在本質(zhì)上,GET請(qǐng)求和POST請(qǐng)求都能拉取數(shù)據(jù)。
這時(shí)候,鄧哥的父親(也就是隔壁老王)出來(lái)了,說(shuō)道:“你是不是傻,去接人開轎車多好啊,開貨車干嘛?費(fèi)油不說(shuō),沒準(zhǔn)人家那還不讓貨車停車呢!”
既然GET和POST都可以做到拉取數(shù)據(jù),那么為什么我們通常拉取數(shù)據(jù)使用GET而不使用POST呢?
在故事中,隔壁老王不讓鄧哥開卡車去接鄧嫂,那么在現(xiàn)實(shí)中,是不是也有一個(gè)“隔壁老王”這樣的角色在限制我們呢?
答案是:有的!這個(gè)現(xiàn)實(shí)中的“隔壁老王”就是ISO國(guó)際標(biāo)準(zhǔn)化組織,這個(gè)組織也說(shuō)了一堆類似隔壁老王的話,這堆話被稱為RFC規(guī)范。
所以說(shuō),我們常說(shuō)的HTTP協(xié)議實(shí)際上是基于RFC規(guī)范的,實(shí)際上GET和POST請(qǐng)求的語(yǔ)法是完全相同的,但是在RFC規(guī)范中,給GET請(qǐng)求和POST請(qǐng)求規(guī)定了語(yǔ)義,規(guī)定GET用來(lái)獲取信息,POST用來(lái)發(fā)送信息。
當(dāng)過年的時(shí)候,鄧哥想要給鄧嫂家送一些年貨的時(shí)候,鄧哥按照隔壁老王的囑咐,開著貨車給鄧嫂家送年貨去了。當(dāng)然,送過去了一些蔬菜也會(huì)稍微拉回來(lái)一點(diǎn)水果~
這就是按照RFC的規(guī)范來(lái)執(zhí)行的,當(dāng)鄧哥想要送年貨的時(shí)候,就會(huì)開貨車過去;在互聯(lián)網(wǎng)環(huán)境中,如果想要發(fā)送信息就要使用POST方法。
POST方法雖然是發(fā)送消息的,但也是有Response的,在請(qǐng)求返回的時(shí)候帶回來(lái)一點(diǎn)數(shù)據(jù)也是被允許的。
那么這時(shí)候問題又來(lái)了,鄧哥如果不聽老王的怎么辦?那這個(gè)規(guī)范不就沒有作用了嗎?這個(gè)時(shí)候老王也是很有辦法的,老王就坐在院子門口,如果鄧哥想運(yùn)貨出去的時(shí)候,開的不是貨車就不讓出院門~
光有規(guī)范沒有具體的軟件實(shí)施也是沒有意義的,所以很多的軟件遵從了RFC的規(guī)范,比如我們熟悉的Chrome瀏覽器。所以我們想用GET方式發(fā)送文件或者圖片是不可能的~就像鄧哥不可能用轎車去給鄧嫂送年貨一樣。
所以我們最后來(lái)總結(jié)一下:
當(dāng)人們問起GET和POST的區(qū)別時(shí),我們要先確定,這里的GET和POST是基于什么前提的?
1. 如果什么前提都沒有,也就是不用任何規(guī)范限制的話,我們只考慮語(yǔ)法來(lái)說(shuō),這兩個(gè)方式是沒有任何區(qū)別的,只有名字不一樣。
2. 如果是基于RFC規(guī)范的,那么問題就又來(lái)了。是基于RFC理論的,還是基于具體的實(shí)現(xiàn)的。
(1)如果是基于RFC理論的,我們稱這個(gè)為Specification。那么GET和POST是具有相同的語(yǔ)法,但是不具備相同的語(yǔ)義,GET方式用作獲取信息,POST方式用作發(fā)送信息。
(2)如果是基于RFC的具體實(shí)現(xiàn)的,我們稱之為implementation。其實(shí)要區(qū)分是具體的哪一種實(shí)現(xiàn)。我們通常默認(rèn)指的是瀏覽器實(shí)現(xiàn)的RFC。當(dāng)然不止瀏覽器,我們?nèi)魏稳硕伎梢栽O(shè)計(jì)一個(gè)HTTP協(xié)議的接口,使用RFC規(guī)范,當(dāng)然這些是我們不用考慮的,因?yàn)椴⒉煌ㄓ谩?/p>
所以我們只需要考慮瀏覽器實(shí)現(xiàn)的RFC,或者說(shuō)Web環(huán)境下的RFC。這個(gè)前提下的答案,就是我們最常見的那些。我就簡(jiǎn)單的列舉在下面了~
a) GET的數(shù)據(jù)在 URL 中對(duì)所有人都是可見的。POST的數(shù)據(jù)不會(huì)顯示在 URL 中。
b) GET對(duì)數(shù)據(jù)長(zhǎng)度有限制,當(dāng)發(fā)送數(shù)據(jù)時(shí),GET 方法向 URL 添加數(shù)據(jù);URL 的長(zhǎng)度是受限制的(URL 的最大長(zhǎng)度是 2048 個(gè)字符)。POST無(wú)限制。
c) GET可收藏為書簽,POST不可收藏為書簽。
d) GET后退按鈕/刷新無(wú)影響,POST數(shù)據(jù)會(huì)被重新提交(瀏覽器應(yīng)該告知用戶數(shù)據(jù)會(huì)被重新提交)。
e) GET編碼類型application/x-www-form-url,POST編碼類型encodedapplication/x-www-form-urlencoded 或 multipart/form-data。為二進(jìn)制數(shù)據(jù)使用多重編碼。
f) GET歷史參數(shù)會(huì)保留在瀏覽器歷史中。POST參數(shù)不會(huì)保存在瀏覽器歷史中。
g) GET只允許 ASCII 字符。POST沒有限制。也允許二進(jìn)制數(shù)據(jù)。
h) 與 POST 相比,GET 的安全性較差,因?yàn)樗l(fā)送的數(shù)據(jù)是 URL 的一部分。在發(fā)送密碼或其他敏感信息時(shí)絕不要使用 GET !POST 比 GET 更安全,因?yàn)閰?shù)不會(huì)被保存在瀏覽器歷史或 web 服務(wù)器日志中。
以上這些點(diǎn)都是我們常見的,還有一些我們不常見的,比如GET請(qǐng)求只會(huì)有一次TCP連接,而POST請(qǐng)求會(huì)有兩次TCP連接。在這背后也有許多的設(shè)計(jì)和考慮~
所以在我們不要認(rèn)為GET和POST請(qǐng)求有什么區(qū)別是一個(gè)很簡(jiǎn)單的問題哦~很多簡(jiǎn)單的問題背后都有著很復(fù)雜的背景。
其實(shí)這也提醒著我們?cè)趯W(xué)習(xí)和生活中不要失去好奇心。就像我們?yōu)槭裁词钦驹诘厍蛏隙皇秋h在空中?太陽(yáng)為什么總是東升西落?天空為什么是藍(lán)色的而不是其他顏色?為什么人類都有眼睛鼻子和嘴?
很多我們認(rèn)為是理所當(dāng)然的背后都有著它理所當(dāng)然的道理。也許這個(gè)道理就是另一個(gè)全新世界的大門~!希望你能夠在這個(gè)浮躁的世界中保持著一顆純潔的好奇心~!