超文本傳輸協議(HTTP)的設計目的是保證客戶機與服務器之間的通訊。html
HTTP 的工做方式是客戶機與服務器之間的請求-應答協議。web
web 瀏覽器多是客戶端,而計算機上的網絡應用程序也可能做爲服務器端。ajax
舉例:客戶端(瀏覽器)向服務器提交 HTTP 請求;服務器向客戶端返回響應。響應包含關於請求的狀態信息以及可能被請求的內容。chrome
在客戶機和服務器之間進行請求-響應時,兩種最常被用到的方法是:GET 和 POST。瀏覽器
查詢字符串(名稱/值對)是在 GET 請求的 URL 中發送的。緩存
/test/demo_form.asp.net?name1=value1&name2=value2安全
在約定中,參數是寫在 ? 後面,用 & 分割。服務器
解析報文的過程是經過獲取 TCP 數據,用正則等工具從數據中獲取 Header 和 Body,從而提取參數。cookie
好比header請求頭中添加token,來驗證用戶是否登陸等權限問題。網絡
也就是說,能夠本身約定參數的寫法,只要服務端可以解釋出來就行,萬變不離其宗。
應用場景:
能夠看到有General 、Response Headers、Request Headers。
有關 GET 請求的其餘一些註釋:
查詢字符串(名稱/值對)是在 POST 請求的 HTTP 消息主體中發送的。
POST /test/demo_form.asp.net HTTP/1.1 Host: baidu.com name1=value1&name2=value2
應用場景:
能夠看到POST請求中多了Form Data(body中的一種表單請求類型)。
有關 POST 請求的其餘一些註釋:
下面的表格比較了兩種 HTTP 方法:GET 和 POST。
GET | POST | |
---|---|---|
後退按鈕/刷新 | 無害 | 數據會被從新提交(瀏覽器應該告知用戶數據會被從新提交)。 |
書籤 | 可收藏爲書籤 | 不可收藏爲書籤 |
緩存 | 能被緩存 | 不能緩存 |
編碼類型 | application/x-www-form-urlencoded | application/x-www-form-urlencoded 或 multipart/form-data。爲二進制數據使用多重編碼。 |
歷史 | 參數保留在瀏覽器歷史中。 | 參數不會保存在瀏覽器歷史中。 |
對數據長度的限制 | 是的。當發送數據時,GET 方法向 URL 添加數據;URL 的長度是受限制的(URL 的最大長度是 2048 個字符)。 | 無限制。 |
對數據類型的限制 | 只容許 ASCII 字符。 | 沒有限制。也容許二進制數據。 |
安全性 | 與 POST 相比,GET 的安全性較差,由於所發送的數據是 URL 的一部分。 在發送密碼或其餘敏感信息時毫不要使用 GET ! |
POST 比 GET 更安全,由於參數不會被保存在瀏覽器歷史或 web 服務器日誌中。 |
可見性 | 數據在 URL 中對全部人都是可見的。 | 數據不會顯示在 URL 中。 |
HTTP請求方法
HTTP請求,最初設定了八種方法。這八種方法本質上沒有任何區別。只是讓請求更加有語義而已。
下面的表格列出了其餘一些 HTTP 請求方法。
方法 | 描述 |
---|---|
OPTIONS | 返回服務器支持的 HTTP 請求方法。 |
GET | 向服務器獲取指定資源。參數放在URL後面。 |
HEAD | 與 GET 相同,但只返回 HTTP 報頭,不返回文檔主體。 |
POST | 向服務器提交數據,數據放在請求體裏。 |
PUT | 上傳指定的 URI 表示。 與POST類似,只是具備冪等特性,通常用於更新。 |
DELETE | 刪除服務器上的指定資源。 |
TRACE | 回顯服務器端收到的請求,測試的時候會用到這個。 |
CONNECT | 把請求鏈接轉換到透明的 TCP/IP 通道。 |
從請求報文上來看,GET、POST的區別以下:
GET 和 POST 只是 HTTP 協議中兩種請求方式(殊途同歸),而 HTTP 協議是基於 TCP/IP 的應用層協議,不管 GET 仍是 POST,用的都是同一個傳輸層協議,因此在傳輸上,沒有任何區別。
若是你要給GET加上request body,技術上是徹底行的通的。
若是你要給給POST帶上url參數,技術上也是徹底行的通的。
可是儘可能不要這麼作,請按照 GET 與 POST 的標準要求去傳遞請求參數。
在萬維網世界中,TCP就像汽車,咱們用TCP來運輸數據,它很可靠,歷來不會發生丟件少件的現象。可是若是路上跑的全是看起來如出一轍的汽車,那這個世界看起來是一團混亂,送急件的汽車可能被前面滿載貨物的汽車攔堵在路上,整個交通系統必定會癱瘓。爲了不這種狀況發生,交通規則HTTP誕生了。
HTTP給汽車運輸設定了好幾個服務類別,有GET, POST, PUT, DELETE等等,HTTP規定,當執行GET請求的時候,要給汽車貼上GET的標籤(設置method爲GET),並且要求把傳送的數據放在車頂上(url中)以方便記錄。若是是POST請求,就要在車上貼上POST的標籤,並把貨物放在車箱裏。固然,你也能夠在GET的時候往車箱內偷偷藏點貨物,可是這是很不光彩;也能夠在POST的時候在車頂上也放一些數據,讓人以爲傻乎乎的。HTTP只是個行爲準則,而TCP纔是GET和POST怎麼實現的基本。
一、正解
(1)HTTP 協議並未規定GET和POST的請求長度限制 ;
(2)所謂的請求長度限制是由瀏覽器和web服務器決定和設置的。各類瀏覽器和web服務器的設定均不同,這依賴於各個瀏覽器廠家的規定或者能夠根據web服務器的處理能力來設定。IE 和 Safari 瀏覽器 限制 2k,Opera 限制4k,Firefox 限制 8k(很是老的版本 256byte),若是超出了最大長度,大部分的服務器直接截斷,也有一些服務器會報414錯誤。
二、各個瀏覽器和web服務器的最大長度總結
瀏覽器
(1)IE:IE瀏覽器(Microsoft Internet Explorer) 對url長度限制是2083(2K+53),超過這個限制,則自動截斷(如果form提交則提交按鈕不起做用)。
(2)Firefox:火狐瀏覽器的url長度限制爲 65536字符,但實際上有效的URL最大長度很多於100,000個字符。
(3)Chrome:谷歌瀏覽的url長度限制超過8182個字符返回本文開頭時列出的錯誤。
(4)Safari:Safari的url長度限制至少爲 80 000 字符。
(5)Opera:Opera 瀏覽器的url長度限制爲190 000 字符。Opera9 地址欄中輸入190000字符時依然能正常編輯。
服務器
(1)Apache:Apache能接受url長度限制爲8 192 字符
(2)IIS:Microsoft Internet Information Server(IIS)能接受url長度限制爲16384個字符。這個是能夠經過修改的(IIS7)
configuration/system.webServer/security/requestFiltering/requestLimits@maxQueryStringsetting.
服務器是由於處理長 URL 要消耗比較多的資源,爲了性能和安全(防止惡意構造長 URL 來攻擊)考慮,會給 URL 長度加限制。
一、post請求包含更多的請求頭
由於post須要在請求的body部分包含數據,因此會多了幾個數據描述部分的首部字段(如:content-type),這實際上是微乎其微的。
二、最重要的一條,post在真正接收數據以前會先將請求頭髮送給服務器進行確認,而後才真正發送數據
post請求的過程:
(1)瀏覽器請求tcp鏈接(第一次握手);
(2)服務器答應進行tcp鏈接(第二次握手);
(3)瀏覽器確認,併發送post請求頭(第三次握手,這個報文比較小,因此http會在此時進行第一次數據發送) ;
(4)服務器返回100 Continue響應 ;
(5)瀏覽器發送數據;
(6)服務器返回200 OK響應。
get請求的過程:
(1)瀏覽器請求tcp鏈接(第一次握手);
(2)服務器答應進行tcp鏈接(第二次握手);
(3)瀏覽器確認,併發送get請求頭和數據(第三次握手,這個報文比較小,因此http會在此時進行第一次數據發送)
(4)服務器返回200 OK響應 。
也就是說,目測get的總耗是post的2/3左右,已經有網友進行過相關的測試。
對於GET方式的請求,瀏覽器會把http header和data一併發送出去,服務器響應200(返回數據);
而對於POST,某些廠商的瀏覽器先發送header,服務器響應100 continue,瀏覽器再發送data,服務器響應200 ok(返回數據)。
由於POST須要兩步,時間上消耗的要多一點,看起來GET比POST更有效。可是請注意如下實際狀況:
一、GET與POST都有本身的語義,不能隨便混用。
二、據研究,在網絡環境好的狀況下,發一次包的時間和發兩次包的時間差異基本能夠無視。
而在網絡環境差的狀況下,兩次包的TCP在驗證數據包完整性上,有很是大的優勢。
三、HTTP 協議中沒有明確說明 POST 會產生兩個 TCP 數據包。
並非全部瀏覽器都會在POST中發送兩次包。
並且實際測試(Chrome、Firefox)發現就只發送一次,header 和 body 不會分開發送。
因此,header 和 body 分開發送是部分瀏覽器或框架的請求方法,不屬於 post 必然行爲。
GET請求參數是在URL後面的,數據在地址欄上可見;POST請求參數放在請求體重,數據在地址欄上不可見,所以有人說POST 比 GET 安全。
然而,從傳輸的角度來講,他們都是不安全的,由於 HTTP 在網絡上是明文傳輸的,只要在網絡節點上捉包,就能完整地獲取數據報文。
要想安全傳輸,就只有加密,也就是 HTTPS。
是否緩存數據,不一樣的瀏覽器廠商的實現方式不同。
《HTTP權威指南》中是這樣說的:http的一次會話須要先創建tcp鏈接(大部分是tcp,可是其餘安全協議也是能夠的),而後才能通訊,若是 每次鏈接都只進行一次http會話,那這個鏈接過程佔的比例太大了!因而出現了持久鏈接:在http/1.0+中是connection首部中添加keep-alive值,在http/1.1中是在connection首部中添加persistent值,固然二者不只僅是命名上的差異,http/1.1中,持久鏈接是默認的,除非顯示在connection中添加close,不然持久鏈接不會關閉,而http/1.0+中則剛好相反,除非顯示在connection首部中添加keep-alive,不然在接收數據包後鏈接就斷開了。
出現了持久鏈接還不夠,在http/1.1中,還有一種稱爲管道通訊的方式進行速度優化:把須要發送到服務器上的全部請求放到輸出隊列中,在第一個請求發送出去後,不等到收到服務器的應答,第二個請求緊接着就發送出去,可是這樣的方式有一個問題:不安全,若是一個管道中有10個鏈接,在發送出9個後,忽然服務器告訴你,鏈接關閉了,此時客戶端即便收到了前9個請求的答覆,也會將這9個請求的內容清空,也就是說,白忙活了……此時,客戶端的這9個請求須要從新發送。這對於冪等請求還好(好比get,多發送幾回都不要緊,每次都是相同的結果),若是是post這樣的非冪等請求(好比支付的時候,多發送幾回就慘了),確定是行不通的。
因此,post請求不能經過管道的方式進行通訊!頗有可能,post請求須要從新創建鏈接,這個過程不跟徹底沒優化的時候同樣了麼?因此,在可使用get請求通訊的時候,不要使用post請求,這樣用戶體驗會更好,固然,若是有安全性要求的話,post會更好。管道化傳輸在瀏覽器端的實現還需考證,貌似默認狀況下大部分瀏覽器(除了opera)是不進行管道化傳輸的,除非手動開啓!