聽(tīng)我講完GET、POST原理,面試官給我倒了杯卡布奇諾
我相信大家在不管是學(xué)習(xí),工作或者面試中,肯定會(huì)碰到或被問(wèn)到
HTTP相關(guān)的知識(shí),今天我們來(lái)聊聊有哪些HTTP請(qǐng)求方式,以及區(qū)別吧!
小伙伴們寫(xiě)過(guò)接口或者使用過(guò)網(wǎng)頁(yè)開(kāi)發(fā)者模式的,肯定對(duì)以下的內(nèi)容不陌生



沒(méi)錯(cuò),這些就是HTTP請(qǐng)求的方式
有一次面試的時(shí)候也被問(wèn)到了這個(gè)問(wèn)題,下面我會(huì)以面試的形式呈現(xiàn)給大家,那么就讓我把大家拉到面試的現(xiàn)場(chǎng)吧!
持續(xù)的腳步聲,由遠(yuǎn)及近,隨之會(huì)議室的門(mén)被推開(kāi)了,我起身定睛一看面試官,他那發(fā)際線即將觸碰到后腦勺,大框黑邊眼鏡也掩蓋不住那黝黑的眼圈,顯得格外的程序員,穿著也非常不拘一格,上半身是襯衣西服,下半身是牛仔褲配拖鞋。

我心中的默念:真大佬,無(wú)疑了!
隨后面試官就讓我坐下,面試就正式拉開(kāi)帷幕!
自我介紹以及其他問(wèn)題此處省略1w字...
面試官:平時(shí)開(kāi)發(fā)過(guò)程中,你們常用的HTTP請(qǐng)求方法都有哪些啊?
我:是這樣的,HTTP/1.1協(xié)議中共定義了八種方法,有時(shí)也叫動(dòng)作,來(lái)表明Request-URL指定的資源不同的操作方式
在HTTP1.0中,定義了三種請(qǐng)求方法: GET, POST 和 HEAD方法。在HTTP1.1中,新增了五種請(qǐng)求方法: OPTIONS, PUT, DELETE, TRACE 和 CONNECT方法 但我們常用的一般就是GET和POST請(qǐng)求。
面試官:嗯,那你說(shuō)說(shuō)GET和POST請(qǐng)求都有哪些區(qū)別呢?(果然進(jìn)套了,看你小子有幾斤幾兩)
我:(我假裝被難住,然后思考了一會(huì)兒說(shuō))這個(gè)。。。沒(méi)有特別去關(guān)注過(guò),但是按照我的理解,大概有這么幾種區(qū)別吧:
GET請(qǐng)求在URL中傳送的參數(shù)是有長(zhǎng)度限制的,而POST沒(méi)有。 GET比POST更不安全,因?yàn)閰?shù)直接暴露在URL上,所以不能用來(lái)傳遞敏感信息。而POST數(shù)據(jù)不會(huì)顯示在URL中。是放在Request body中。 對(duì)參數(shù)的數(shù)據(jù)類(lèi)型,GET只接受ASCII字符,而POST沒(méi)有限制。 GET請(qǐng)求參數(shù)會(huì)被完整保留在瀏覽器歷史記錄里;相反,POST請(qǐng)求參數(shù)也不會(huì)被瀏覽器保留。 GET請(qǐng)求只能進(jìn)行url編碼( application/x-www-form-urlencoded),而POST支持多種編碼方式。 GET請(qǐng)求會(huì)被瀏覽器主動(dòng)緩存,而POST不會(huì),除非手動(dòng)設(shè)置。 GET在瀏覽器回退時(shí)是無(wú)害的,而POST會(huì)再次提交請(qǐng)求。
面試官心里:(沒(méi)關(guān)注過(guò),那你還背的一條不差。跟我擱這兒裝杯呢?看我怎么教育你。)
面試官:那Get請(qǐng)求有Request body么?如果有的話參數(shù)可以像Post請(qǐng)求一樣放在里面么?
我:(吼吼,看來(lái)有機(jī)會(huì)把我昨天精心準(zhǔn)備的東西給他扯半小時(shí)了[手動(dòng)撓頭] 讓開(kāi),我要開(kāi)始放大招了)
其實(shí)吧,GET和POST在本質(zhì)上沒(méi)有區(qū)別,都是HTTP協(xié)議中的兩種發(fā)送請(qǐng)求的方法。而HTTP呢,是基于TCP/IP的關(guān)于數(shù)據(jù)如何在萬(wàn)維網(wǎng)中如何通信的協(xié)議。
萬(wàn)維網(wǎng):簡(jiǎn)稱WWW,是World Wide Web的簡(jiǎn)稱,也稱為Web、3W等
HTTP的底層是TCP/IP。所以GET和POST的底層也是TCP/IP,也就是說(shuō),GET/POST都是TCP鏈接。
GET和POST能做的事情是一樣一樣的。你要給GET加上request body,給POST帶上url參數(shù),技術(shù)上是完全行的通的。
舉個(gè)栗子吧:(嗯?栗子?好餓,待會(huì)兒面試完去買(mǎi)點(diǎn))
TCP就像汽車(chē),我們用TCP來(lái)運(yùn)輸數(shù)據(jù),它很可靠,從來(lái)不會(huì)發(fā)生丟件少件的現(xiàn)象。
但是如果路上跑的全是看起來(lái)一模一樣的汽車(chē),那這個(gè)世界看起來(lái)是一團(tuán)混亂,送急件的汽車(chē)可能被前面滿載貨物的汽車(chē)攔堵在路上,整個(gè)交通系統(tǒng)一定會(huì)癱瘓。
為了避免這種情況發(fā)生,交通規(guī)則HTTP誕生了。HTTP給汽車(chē)運(yùn)輸設(shè)定了好幾個(gè)服務(wù)類(lèi)別,包括GET, POST, PUT等等,
HTTP規(guī)定,當(dāng)執(zhí)行GET請(qǐng)求的時(shí)候,要給汽車(chē)貼上GET的標(biāo)簽(設(shè)置method為GET),而且要求把傳送的數(shù)據(jù)放在車(chē)頂上(url中)以方便記錄。
如果是POST請(qǐng)求,就要在車(chē)上貼上POST的標(biāo)簽,并把貨物放在車(chē)廂里(request body中)。
當(dāng)然,你也可以在用GET的時(shí)往車(chē)廂內(nèi)偷偷藏點(diǎn)貨物,但這并不不光彩;也可以在POST的時(shí)候在車(chē)頂上也放一些數(shù)據(jù),也會(huì)讓人覺(jué)得傻乎乎的。
HTTP只是個(gè)行為準(zhǔn)則,而GET和POST本質(zhì)上就是TCP鏈接,并無(wú)差別。但是由于HTTP的規(guī)定和瀏覽器/服務(wù)器的限制,導(dǎo)致他們?cè)趹?yīng)用過(guò)程中體現(xiàn)出一些不同。
面試官心里:(哎呀,這小子還真的了解這塊兒啊,看來(lái)是我誤會(huì)他了,難道遇到了大佬?)
面試官:你說(shuō)的不錯(cuò),那你剛才說(shuō)的URL中傳送參數(shù)的長(zhǎng)度限制在Get和Post中都是怎么樣的呢?
我:其實(shí)在Web中啊,還有另一個(gè)重要的角色:運(yùn)輸公司。
不同的瀏覽器Client端(發(fā)起http請(qǐng)求)和服務(wù)器server端(接受http請(qǐng)求)就是不同的運(yùn)輸公司。
雖然理論上,你可以在車(chē)頂上無(wú)限的堆貨物(url中無(wú)限加參數(shù))。但是運(yùn)輸公司可不傻,裝貨和卸貨也是有很大成本的,他們會(huì)限制單次運(yùn)輸量來(lái)控制風(fēng)險(xiǎn),數(shù)據(jù)量太大對(duì)瀏覽器和服務(wù)器都是很大負(fù)擔(dān)。
業(yè)界不成文的規(guī)定是,(大多數(shù))瀏覽器通常都會(huì)限制url長(zhǎng)度在2K個(gè)字節(jié),而(大多數(shù))服務(wù)器最多處理64K大小的url。
超過(guò)的部分,恕不處理。如果你用GET服務(wù),在request body偷偷藏了數(shù)據(jù),不同服務(wù)器的處理方式也是不同的,有些服務(wù)器會(huì)幫你卸貨,讀出數(shù)據(jù),有些服務(wù)器直接忽略。
所以,雖然GET可以帶request body,卻不能保證一定能被接收到。
面試官:(看來(lái)理論確實(shí)是掌握的不錯(cuò),讓我考考他實(shí)際應(yīng)用)那GET 方法參數(shù)寫(xiě)法是固定的嗎?
我:在約定中,我們的參數(shù)是寫(xiě)在?后面,用&分割。就像下面這樣:
http://ip:port/test/getHelloWorld?username=langwang&age=26&sex=2
我們知道,解析報(bào)文的過(guò)程是通過(guò)獲取 TCP 數(shù)據(jù),用正則等工具從數(shù)據(jù)中獲取 Header 和 Body,從而提取參數(shù)。
比如header請(qǐng)求頭中添加token,來(lái)驗(yàn)證用戶是否登錄等權(quán)限問(wèn)題。
也就是說(shuō),我們可以自己約定參數(shù)的寫(xiě)法,只要服務(wù)端能夠解釋出來(lái)就行,萬(wàn)變不離其宗。
面試官:那么說(shuō)來(lái),是不是POST 方法比 GET 方法更安全呢?
我:有人說(shuō)POST 比 GET 安全,因?yàn)閿?shù)據(jù)在地址欄上不可見(jiàn)。
然而,從傳輸?shù)慕嵌葋?lái)說(shuō),他們都是不安全的,因?yàn)?HTTP 在網(wǎng)絡(luò)上是明文傳輸的,只要在網(wǎng)絡(luò)節(jié)點(diǎn)上捉包,就能完整地獲取數(shù)據(jù)報(bào)文。
其實(shí),要想安全傳輸,就只有加密,也就是 HTTPS。
面試官:嗯,不錯(cuò)不錯(cuò),看來(lái)你對(duì)HTTP協(xié)議這塊兒還是有一定了解的,那么你知道Get、Post請(qǐng)求發(fā)送的數(shù)據(jù)包有什么不同嗎?
我:(看來(lái)這面試官是非要是把我問(wèn)倒才滿意啊?可惜可惜。看我套路他一波)
面試官,實(shí)不相瞞,我上家公司加班比較多,最近剛簽完離職,貴公司是我面得第一家公司,所以準(zhǔn)備的不充分,這樣吧,我大致談?wù)勎业睦斫獍桑粚?duì)的地方您見(jiàn)諒。
面試官:沒(méi)關(guān)系,按你的理解聊聊就行。(這小子沒(méi)準(zhǔn)備就說(shuō)成這樣,我的好好考慮一下,別錯(cuò)失了先機(jī),失去一個(gè)能為公司加班的人才)
我:嗯嗯,是這樣的,GET請(qǐng)求時(shí)產(chǎn)生一個(gè)TCP數(shù)據(jù)包;POST請(qǐng)求時(shí)產(chǎn)生兩個(gè)TCP數(shù)據(jù)包。
GET:瀏覽器會(huì)把http header和data一并發(fā)送出去,服務(wù)器響應(yīng)200(返回?cái)?shù)據(jù)); POST:瀏覽器先發(fā)送header,服務(wù)器響應(yīng)100 continue,瀏覽器再發(fā)送data,服務(wù)器響應(yīng)200 OK(返回?cái)?shù)據(jù))。
就像是GET只需要汽車(chē)跑一趟就把貨送到了,而POST得跑兩趟,第一趟,先去和服務(wù)器打個(gè)招呼老鐵,我等下要送一批貨來(lái),你們準(zhǔn)備接收一下哈,然后再回頭把貨送過(guò)去。
因?yàn)镻OST需要兩步,理論上時(shí)間上消耗的要多一點(diǎn),看起來(lái)GET比POST更有效。但并不是,后來(lái)發(fā)現(xiàn)原來(lái)是個(gè)坑。在我看來(lái):
GET與POST都有自己的語(yǔ)義,不能隨便混用。 據(jù)研究,在網(wǎng)絡(luò)環(huán)境好的情況下,發(fā)一次包的時(shí)間和發(fā)兩次包的時(shí)間差別基本可以無(wú)視。而在網(wǎng)絡(luò)環(huán)境差的情況下,兩次包的TCP在驗(yàn)證數(shù)據(jù)包完整性上,有非常大的優(yōu)點(diǎn)。 并不是所有瀏覽器都會(huì)在POST中發(fā)送兩次包,F(xiàn)irefox就只發(fā)送一次。我去年用Chrome瀏覽器測(cè)試發(fā)現(xiàn)也是只發(fā)送一次,所以我認(rèn)為Get、POST性能差可以人為忽略。
面試官:嗯,你說(shuō)的很不錯(cuò),那你稍微等一下啊。
我:(難道還有變故?這波操作難道被發(fā)現(xiàn)了我在套路面試官?不應(yīng)該啊)
五分鐘后,面試官拿著一杯飲料走了進(jìn)來(lái)。。。。
面試官:你嘗嘗這咖啡味道如何?(自古套路得人心,學(xué)好了)
我喝了一口,豎起大拇指說(shuō)到:面試官,這是正宗的卡布奇諾啊,我平時(shí)就喜歡喝,可惜太貴了。。
咦?我進(jìn)來(lái)之前沒(méi)有看到你們這有咖啡店呀,這是?
面試官嘴角上翹,微微一笑,露出了潔白的兩顆大門(mén)牙說(shuō)到:
我看你簡(jiǎn)歷說(shuō)你愛(ài)喝咖啡,巧了,我們公司有專門(mén)的水吧,福利之一就是是每天免費(fèi)一杯咖啡或飲料。以后你可以經(jīng)常喝了。
我:那您的意思是,我面試過(guò)了是么,太好了!對(duì)了水吧每天幾點(diǎn)下班吶?跟開(kāi)發(fā)一個(gè)點(diǎn)兒么?(不會(huì)是因?yàn)榻?jīng)常加班才免費(fèi)喝咖啡吧,我得試探試探)
面試官:哈哈是啊,水吧一直都是按點(diǎn)下班,咱們公司如果有人加班的話,可以自己去水吧做著喝就行,加班時(shí)間都是免費(fèi)的。你這兒沒(méi)問(wèn)題的話,我看下周一就入職吧。
我:好的,面試官,我回去考慮下,到時(shí)候和您聯(lián)系,再見(jiàn)!
至此,本次關(guān)于HTTP請(qǐng)求方式,以及GET和POST的區(qū)別相關(guān)的面試就結(jié)束啦,感謝大家的觀看!
好了。今天就說(shuō)到這了,我還會(huì)不斷分享自己的所學(xué)所想,希望我們一起走在成功的道路上!
