本篇文章為大家展示了GET和POST請(qǐng)求有什么區(qū)別,內(nèi)容簡(jiǎn)明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過(guò)這篇文章的詳細(xì)介紹希望你能有所收獲。
十余年的桐柏網(wǎng)站建設(shè)經(jīng)驗(yàn),針對(duì)設(shè)計(jì)、前端、開(kāi)發(fā)、售后、文案、推廣等六對(duì)一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。全網(wǎng)營(yíng)銷(xiāo)推廣的優(yōu)勢(shì)是能夠根據(jù)用戶(hù)設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整桐柏建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無(wú)論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。創(chuàng)新互聯(lián)建站從事“桐柏網(wǎng)站設(shè)計(jì)”,“桐柏網(wǎng)站推廣”以來(lái),每個(gè)客戶(hù)項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。
有沒(méi)有簡(jiǎn)單的答案?
有的,我們?nèi)f能的w3schools可以看到答案,英文點(diǎn)這里,中文點(diǎn)這里可以看到原始的網(wǎng)頁(yè)。
GET | POST | |
---|---|---|
后退按鈕/刷新 | 無(wú)害 | 數(shù)據(jù)會(huì)被重新提交(瀏覽器應(yīng)該告知用戶(hù)數(shù)據(jù)會(huì)被重新提交)。 |
書(shū)簽 | 可收藏為書(shū)簽 | 不可收藏為書(shū)簽 |
緩存 | 能被緩存 | 不能緩存 |
編碼類(lèi)型 | application/x-www-form-urlencoded | application/x-www-form-urlencoded或multipart/form-data。為二進(jìn)制數(shù)據(jù)使用多重編碼。 |
歷史 | 參數(shù)保留在瀏覽器歷史中。 | 參數(shù)不會(huì)保存在瀏覽器歷史中。 |
對(duì)數(shù)據(jù)長(zhǎng)度的限制 | 是的。當(dāng)發(fā)送數(shù)據(jù)時(shí),GET方法向URL添加數(shù)據(jù);URL的長(zhǎng)度是受限制的(URL的最大長(zhǎng)度是2048個(gè)字符)。 | 無(wú)限制。 |
對(duì)數(shù)據(jù)類(lèi)型的限制 | 只允許ASCII字符。 | 沒(méi)有限制。也允許二進(jìn)制數(shù)據(jù)。 |
安全性 | 與POST相比,GET的安全性較差,因?yàn)樗l(fā)送的數(shù)據(jù)是URL的一部分。在發(fā)送密碼或其他敏感信息時(shí)絕不要使用GET! | POST比GET更安全,因?yàn)閰?shù)不會(huì)被保存在瀏覽器歷史或web服務(wù)器日志中。 |
可見(jiàn)性 | 數(shù)據(jù)在URL中對(duì)所有人都是可見(jiàn)的。 | 數(shù)據(jù)不會(huì)顯示在URL中。 |
這個(gè)就是我們常說(shuō)的GET和POST了。但是這并不是真正的GET和POST協(xié)議,而是我們常用瀏覽器(部分瀏覽器不一樣)的封裝后的樣子。所以我也想聊一下關(guān)于瀏覽器和協(xié)議對(duì)HTTP通訊協(xié)議封裝的區(qū)別。
GET和POST都是基于HTTP協(xié)議。在計(jì)算機(jī)網(wǎng)絡(luò)7層的協(xié)議模型中,HTTP協(xié)議是隸屬于最高層應(yīng)用層的。也是一種基于第四層傳輸層TCP/IP協(xié)議的。這也導(dǎo)致了本質(zhì)上GET和POST這兩種請(qǐng)求其實(shí)是沒(méi)有太大的區(qū)別的。區(qū)別只是請(qǐng)求的報(bào)文格式不一樣而已。 如果我們把這兩種請(qǐng)求用最短的方式,沒(méi)有任何參數(shù)的展現(xiàn)成HTTP報(bào)文信息,其實(shí)就沒(méi)有什么太大區(qū)別了,如下
GET /test HTTP/1.1 Host: localhost:8080
POST /test HTTP/1.1 Host: localhost:8080
GET是為了獲得信息從服務(wù)器到本地,POST是為了推送信息從本地到服務(wù)器,行為上是兩種截然相反的操作。
由于GET方法的目的就是為了獲取信息,當(dāng)我們假設(shè)如果數(shù)據(jù)庫(kù)的數(shù)據(jù)不變,請(qǐng)求的參數(shù)不變(基于當(dāng)前時(shí)間的參數(shù),應(yīng)當(dāng)認(rèn)為請(qǐng)求參數(shù)是變化的,比如last_5_minutes),那么我們返回的結(jié)果也應(yīng)該是不變的。反復(fù)的讀取數(shù)據(jù)庫(kù)中的數(shù)據(jù),不應(yīng)該對(duì)數(shù)據(jù)本身產(chǎn)生副作用(統(tǒng)計(jì)信息除外)。所以我們說(shuō)GET是符合冪等性(idempotent)。因此可以被瀏覽器與其他客戶(hù)端緩存。
POST方法的目的是創(chuàng)建資源,即使我們請(qǐng)求的參數(shù)不變,但是對(duì)數(shù)據(jù)庫(kù)而言都是要?jiǎng)?chuàng)建一個(gè)新的記錄,雖然所有的數(shù)值都和前面的一樣,但是這也是可以合理存在的,只是在數(shù)據(jù)庫(kù)中主鍵不同罷了。這樣的創(chuàng)建流程對(duì)數(shù)據(jù)庫(kù)的數(shù)據(jù)有實(shí)質(zhì)影響,每創(chuàng)建一次就多一條數(shù)據(jù)。因此我們說(shuō)POST是不符合冪等性的。因此也不可以被緩存。試想一下,如果POST請(qǐng)求可以被緩存,我們想在電商網(wǎng)站買(mǎi)東西,前后下單2次,都是一樣的東西。POST返回的信息是直接掃描本地緩存,直接返回第一次的下的成功,并沒(méi)有進(jìn)行第二次的下單提交。或者如果可以用書(shū)簽保存鏈接,是不是點(diǎn)一次書(shū)簽查看就下了一次訂單?此外在發(fā)出POST請(qǐng)求后,有些頁(yè)面刷新的時(shí)候回彈出窗口 “確認(rèn)重新提交表單”。這些都是POST不能被緩存的原因了。
但是如果說(shuō)到實(shí)際使用,也不是不可以交換功能。畢竟都是使用相同的協(xié)議。所以我可以設(shè)計(jì)一個(gè)API,用GET方法的請(qǐng)求來(lái)插入數(shù)據(jù),用POST方法的請(qǐng)求來(lái)返回查詢(xún)數(shù)據(jù)。也許用POST方法請(qǐng)求數(shù)據(jù)還能理解,但是堅(jiān)決不推薦用GET方法來(lái)插入數(shù)據(jù),這樣做只會(huì)徒增維護(hù)難度。
特點(diǎn) | 瀏覽器GET | 瀏覽器POST | RESTful接口GET | RESTful接口POST |
---|---|---|---|---|
使用場(chǎng)景 | 特指在瀏覽器中不使用Ajax的HTTP請(qǐng)求,也就是原生的那些請(qǐng)求,可以追溯到HTML誕生的時(shí)候。 | 特指在瀏覽器中Ajax API,Java中的httpClient,postman工具等發(fā)出的請(qǐng)求。 | ||
后退按鈕/刷新 | 無(wú)害 | 數(shù)據(jù)會(huì)被重新提交(瀏覽器應(yīng)該告知用戶(hù)數(shù)據(jù)會(huì)被重新提交) | 無(wú)害 | 數(shù)據(jù)會(huì)被重新提交 |
書(shū)簽 | 可收藏為書(shū)簽 | 不可收藏為書(shū)簽 | 沒(méi)有此功能 | 沒(méi)有此功能 |
緩存 | 能被緩存 | 不能緩存 | 能被緩存 | 能被緩存,但非常不推薦 |
編碼類(lèi)型 | application/x-www-form-urlencoded | application/x-www-form-urlencoded或multipart/form-data。為二進(jìn)制數(shù)據(jù)使用多重編碼。 | 多重編碼類(lèi)型均可 | 多重編碼類(lèi)型均可 |
歷史 | 參數(shù)保留在瀏覽器歷史中。 | 參數(shù)不會(huì)保存在瀏覽器歷史中。 | -- | -- |
對(duì)數(shù)據(jù)長(zhǎng)度的限制 | 是的。當(dāng)發(fā)送數(shù)據(jù)時(shí),GET方法向URL添加數(shù)據(jù);URL的長(zhǎng)度是受限制的(URL的最大長(zhǎng)度是2048個(gè)字符) | 無(wú)限制 | 無(wú)限制 | 無(wú)限制 |
對(duì)數(shù)據(jù)類(lèi)型的限制 | 只允許ASCII字符。 | 沒(méi)有限制。也允許二進(jìn)制數(shù)據(jù)。 | 無(wú)限制 | 無(wú)限制 |
安全性 | 與POST相比,GET的安全性較差,因?yàn)樗l(fā)送的數(shù)據(jù)是URL的一部分。在發(fā)送密碼或其他敏感信息時(shí)絕不要使用GET! | POST比GET更安全,因?yàn)閰?shù)不會(huì)被保存在瀏覽器歷史或web服務(wù)器日志中。 | 不安全 | 不安全 |
可見(jiàn)性 | 數(shù)據(jù)在URL中對(duì)所有人都是可見(jiàn)的。 | 數(shù)據(jù)不會(huì)顯示在URL中。 | -- | -- |
我們先來(lái)看看在1999年6月的RFC2616-4.3HTTP協(xié)議1.1中第33頁(yè)提及到內(nèi)容如下:
A server SHOULD read and forward a message-body on any request; if the request method does not include defined semantics for an entity-body, then the message-body SHOULD be ignored when handling the request.
然而RFC2616-4.3已經(jīng)過(guò)時(shí)了,推出了新的修正RFC7230-3.3。但是問(wèn)題是最新的規(guī)范居然是更加寬松?我對(duì)此表示很無(wú)奈。
我們?cè)賮?lái)看看在2014年6月的RFC7230-3.3HTTP協(xié)議1.1消息語(yǔ)法和轉(zhuǎn)發(fā)中第28頁(yè)提及到內(nèi)容如下:
The presence of a message body in a request is signaled by a Content-Length or Transfer-Encoding header field. Request message framing is independent of method semantics, even if the method does not define any use for a message body.
所以從現(xiàn)在最新的協(xié)議來(lái)看,攜帶body信息已經(jīng)無(wú)所謂使用的是什么方法了。但是我真的建議在GET請(qǐng)求中不要帶body。
首先我們要明確的是我們經(jīng)常說(shuō)的GET請(qǐng)求長(zhǎng)度限制是之URI請(qǐng)求長(zhǎng)度限制。
我們先來(lái)看看在1999年6月的RFC2616-3.2.1
The HTTP protocol does not place any a priori limit on the length of a URI. Servers MUST be able to handle the URI of any resource they serve, and SHOULD be able to handle URIs of unbounded length if they provide GET-based forms that could generate such URIs.
我們?cè)賮?lái)看看2014年6月的RFC7230-2.5HTTP協(xié)議1.1消息語(yǔ)法和轉(zhuǎn)發(fā)中第13頁(yè)提及到內(nèi)容如下:
HTTP does not have specific length limitations for many of its protocol elements because the lengths that might be appropriate will vary widely, depending on the deployment context and purpose of the implementation.
我們同樣來(lái)看看2014年6月的RFC7230-3.1.1HTTP協(xié)議1.1消息語(yǔ)法和轉(zhuǎn)發(fā)中第21頁(yè)提及到內(nèi)容如下:
HTTP does not place a predefined limit on the length of a request-line, as described in Section 2.5. A server that receives a method longer than any that it implements SHOULD respond with a 501(Not Implemented) status code. A server that receives a request-target longer than any URI it wishes to parse MUST respond with a 414 (URI Too Long) status code (see Section 6.5.12 of [RFC7231]).
這就是HTTP協(xié)議規(guī)范里的要求,從來(lái)沒(méi)有要求過(guò)URI的長(zhǎng)度限制,但是為什么我們會(huì)有URL長(zhǎng)度限制的問(wèn)題呢? 我們?cè)賮?lái)看看微軟谷歌等大廠(chǎng)的規(guī)范
微軟 IE瀏覽器的規(guī)范
Microsoft Internet Explorer has a maximum uniform resource locator (URL) length of 2,083 characters. Internet Explorer also has a maximum path length of 2,048 characters. This limit applies to both POST request and GET request URLs.
Google Chrome瀏覽器的規(guī)范
In general, the web platform does not have limits on the length of URLs (although 2^31 is a common limit). Chrome limits URLs to a maximum length of 2MB for practical reasons and to avoid causing denial-of-service problems in inter-process communication.
所以現(xiàn)在我們現(xiàn)在知道URI長(zhǎng)度限制只是各個(gè)瀏覽器廠(chǎng)商自己的限制,且限制還不統(tǒng)一。而HTTP規(guī)范根本就沒(méi)有規(guī)定最長(zhǎng)長(zhǎng)度限制,也就是說(shuō)看你的服務(wù)器自己決定吧。
網(wǎng)上很多人都說(shuō)POST方法比GET方法更安全,主要是POST數(shù)據(jù)部分不直接暴露在URL上,而GET的參數(shù)全都在URL上,更容易看到。但是,從傳輸數(shù)據(jù)上來(lái)看,他們都是明文傳輸,每次請(qǐng)求和返回的字節(jié)都會(huì)以明文的形式在網(wǎng)上傳輸。如果想要安全傳輸,通用的做法是使用SSL協(xié)議來(lái)加密,也就是業(yè)界的標(biāo)準(zhǔn)規(guī)范HTTPS。當(dāng)然HTTP協(xié)議和SSL協(xié)議是兩個(gè)獨(dú)立的協(xié)議。如果你有幸參與一些特殊項(xiàng)目,那么HTTP可能就不是用SSL協(xié)議加密了,也許會(huì)換成國(guó)密SM協(xié)議,參見(jiàn)國(guó)密標(biāo)準(zhǔn)網(wǎng)密碼標(biāo)準(zhǔn)應(yīng)用指南。
所以在網(wǎng)上傳輸數(shù)據(jù)如果想要更安全,一定要用HTTPS協(xié)議。但在網(wǎng)頁(yè)設(shè)計(jì)上,決定不能把密碼密鑰一類(lèi)的東西用URL傳輸,畢竟還是有可能使用者被身后的人偷窺到URL上的信息。
網(wǎng)上很多人說(shuō)GET方式的請(qǐng)求,瀏覽器會(huì)把請(qǐng)求HEADER和參數(shù)一并發(fā)送出去,服務(wù)端響應(yīng)200,請(qǐng)求成功。而POST方式的請(qǐng)求,瀏覽器會(huì)先發(fā)送HEADER給服務(wù)器,服務(wù)器響應(yīng)代碼100 continue,瀏覽器再發(fā)送一個(gè)DATA給服務(wù)器,服務(wù)器響應(yīng)200,請(qǐng)求成功。
然而這也只是說(shuō)瀏覽器會(huì)這樣做,并不是HTTP協(xié)議中的規(guī)范。這一點(diǎn)和我們剛才提到的URI的長(zhǎng)度一樣,都是由各個(gè)瀏覽器廠(chǎng)商所制定的規(guī)則。我們假設(shè)一下,如果GET方法的URL太長(zhǎng)一個(gè)TCP包放不下怎么辦,那是不是GET也要發(fā)2個(gè)TCP包?而且FireFox瀏覽器針對(duì)POST的小數(shù)據(jù)發(fā)送也是一個(gè)TCP包,這又怎么解釋?zhuān)克宰詈侠淼姆椒ň褪且罁?jù)瀏覽器和客戶(hù)端的自身規(guī)則而定。
如果數(shù)據(jù)量很小,1次TCP包和2次TCP包沒(méi)有太大的時(shí)間差。如果數(shù)據(jù)量很大,通常POST請(qǐng)求不是一次TCP包能包含所有的。應(yīng)該會(huì)有很多的TCP包。如果先發(fā)一個(gè)HEAD過(guò)去,如果服務(wù)器沒(méi)有回應(yīng),那么數(shù)據(jù)包的部分就可以不發(fā)送了。但服務(wù)器都響應(yīng)失敗了,你還在乎是否發(fā)送1次還是2次?
回到文章標(biāo)題,再換一種說(shuō)法,如果有人問(wèn)你GET和POST的區(qū)別,我們來(lái)回答發(fā)送1次還是2次TCP包的問(wèn)題,你覺(jué)得你用傳輸層協(xié)議(TCP)的答案能回答應(yīng)用層協(xié)議(HTTP)的問(wèn)題?
上述內(nèi)容就是GET和POST請(qǐng)求有什么區(qū)別,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。