我终于知道post和get的区别
IT界知名的程序員曾說:對于那些月薪三萬以下,自稱IT工程師的碼農們,其實我們從來沒有把他們歸為我們IT工程師的隊伍。他們雖然總是以IT工程師自居,但只是他們一廂情愿罷了。
碼農:你知道get和post請求到底有什么區(qū)別?
前言
這個問題幾乎面試的時候都會問到,是一個老生常談的話題,然而隨著不斷的學習,對于以前的認識有很多誤區(qū),所以還是需要不斷地總結的,學而時習之,不亦說乎。
01
1.1 http的特點
- 基于tcp/ip、一種網絡應用層協(xié)議、超文本傳輸協(xié)議HyperText Transfer Protocol
- 工作方式:客戶端請求服務端應答的模式
- 快速:無狀態(tài)連接
- 靈活:可以傳輸任意對象,對象類型由Content-Type標記
- 客戶端請求request消息包括以下格式:請求行(request line)、請求頭部(header)、空行、請求數(shù)據(jù)
服務端響應response也由四個部分組成,分別是:狀態(tài)行、消息報頭、空行、響應正文
1.2 請求方法
http請求可以使用多種請求方法。HTTP1.0定義了三種請求方法:GET, POST 和 HEAD方法。
HTTP1.1新增了五種請求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。
- 1 GET 請求指定的頁面信息,并返回實體主體。
- 2 HEAD 類似于get請求,只不過返回的響應中沒有具體的內容,用于獲取報頭
- 3 POST 向指定資源提交數(shù)據(jù)進行處理請求(例如提交表單或者上傳文件)。數(shù)據(jù)被包含在請求體中。POST請求可能會導致新的資源的建立和/或已有資源的修改。
- 4 PUT 從客戶端向服務器傳送的數(shù)據(jù)取代指定的文檔的內容。
- 5 DELETE 請求服務器刪除指定的頁面。
- 6 CONNECT HTTP/1.1協(xié)議中預留給能夠將連接改為管道方式的代理服務器。
- 7 OPTIONS 允許客戶端查看服務器的性能。
- 8 TRACE 回顯服務器收到的請求,主要用于測試或診斷。
1.3 我們耳熟能詳?shù)牡膮^(qū)別
http協(xié)議最常見的兩種方法GET和POST,這幾點答案其實有幾點并不準確
請求緩存:GET 會被緩存,而post不會
收藏書簽:GET可以,而POST不能
保留瀏覽器歷史記錄:GET可以,而POST不能
用處:get常用于取回數(shù)據(jù),post用于提交數(shù)據(jù)
安全性:post比get安全
請求參數(shù):querystring 是url的一部分get、post都可以帶上。get的querystring(僅支持urlencode編碼),post的參數(shù)是放在body(支持多種編碼)
請求參數(shù)長度限制:get請求長度最多1024kb,post對請求數(shù)據(jù)沒有限制
02
get和post誤區(qū)針對上面常見的區(qū)別,如果面試的時候這么說,肯定是有很大的毛病,剛在學校面試的時候也曾經囫圇吞棗地這樣說過,現(xiàn)在回過頭再想以前的錯誤認知,又有許多新的認識,學習就是不斷刷新認知
2.1 誤區(qū)一
“用處:get常用于取回數(shù)據(jù),post用于提交數(shù)據(jù)”
曾聽到過這樣一種說法:get替換post來優(yōu)化網站性能,雖然這種說法沒錯,也的確get常被用于取回數(shù)據(jù),但是post也被一些ui框架使用于取回數(shù)據(jù),比如kendo ui中的grid,就是用post來接受數(shù)據(jù)的。所以結論是get、post用途也是因地制宜。如果你有使用過kendo UI,會發(fā)現(xiàn)分頁、過濾、自定義的參數(shù)都包含在form data里面。
請求參數(shù)get是querystring(僅支持urlencode編碼),post是放在body(支持多種編碼) query參數(shù)是URL的一部分,而GET、POST等是請求方法的一種,不管是哪種請求方法,都必須有URL,而URL的query是可選的,可有可無。
2.2 誤區(qū)二
“請求參數(shù)長度限制:get請求長度最多1024kb,post對請求數(shù)據(jù)沒有限制”
這句話看上去實在沒毛病啊,菜鳥教程也是這樣說的啊。雖然字面意思上沒有錯誤,但是理解一定要正確。我想說的是GET方法提交的url參數(shù)數(shù)據(jù)大小沒有限制,在http協(xié)議中沒有對url長度進行限制(不僅僅是querystring的長度),這個限制是特定的瀏覽器及服務器對他的限制
下面就是對各種瀏覽器和服務器的最大處理能力做一些說明
- IE瀏覽器對URL的最大限制為2083個字符
- Firefox (Browser):對于Firefox瀏覽器URL的長度限制為65,536個字符。
- Safari (Browser):URL最大長度限制為 80,000個字符。
- Opera (Browser):URL最大長度限制為190,000個字符。
- Google (chrome):URL最大長度限制為8182個字符。
- Apache (Server):能接受最大url長度為8,192個字符。
- Microsoft Internet Information Server(IIS):能接受最大url的長度為16,384個字符。
所以為了符合所有標準,url的最好不好超過最低標準的2083個字符(2k+35)。當然在做客戶端程序時,url并不展示給用戶,只是個程序調用,這時長度只收web服務器的影響了。對于中文的傳遞,一個漢字最終編碼后的字符長度是9個字符。
最常見的form表單,瀏覽器默認的form表單,默認的content-type是application/x-www-form-urlencoded,提交的數(shù)據(jù)會按照key value的方式,jquery的ajax默認的也是這種content-type。當然在post方式中添加querystring一定是可以接收的到,但是在get方式中加body參數(shù)就不一定能成功接收到了。
2.3 誤區(qū)三
“post比get安全性要高”
這里的安全是相對性,并不是真正意義上的安全,通過get提交的數(shù)據(jù)都將顯示到url上,頁面會被瀏覽器緩存,其他人查看歷史記錄會看到提交的數(shù)據(jù),而post不會。另外get提交數(shù)據(jù)還可能會造成CSRF攻擊。
2.4 誤區(qū)四:“GET產生一個TCP數(shù)據(jù)包;POST產生兩個TCP數(shù)據(jù)包。”
這一點理解起來還是有一定難度的,實際上,不論哪一種瀏覽器,在發(fā)送 POST 的時候都沒有帶 Expect 頭,server 也自然不會發(fā) 100 continue。通過抓包發(fā)現(xiàn),盡管會分兩次,body 就是緊隨在 header 后面發(fā)送的,根本不存在『等待服務器響應』這一說。
從另一個角度說,TCP 是傳輸層協(xié)議。別人問你應用層協(xié)議里的 GET 和 POST 有啥區(qū)別,你回答說這倆在傳輸層上發(fā)送數(shù)據(jù)的時候不一樣,確定別人不抽你?參考資料:https://zhuanlan.zhihu.com/p/25028045
03
附錄常見的http狀態(tài)碼
| 1* | 信息,服務器收到請求,需要請求者繼續(xù)執(zhí)行操作 |
| 2* | 成功,操作被成功接收并處理 |
| 3* | 重定向,需要進一步的操作以完成請求 |
| 4* | 客戶端錯誤,請求包含語法錯誤或無法完成請求 |
| 5* | 服務器錯誤,服務器在處理請求的過程中發(fā)生了錯誤 |
3.1 狀態(tài)碼1xx
- 100 Continue:服務器僅接收到部分請求,但是一旦服務器并沒有拒絕該請求,客戶端應該繼續(xù)發(fā)送其余的請求。
- 101 Switching Protocols:服務器轉換協(xié)議:服務器將遵從客戶的請求轉換到另外一種協(xié)議。
- 102: 由WebDAV(RFC 2518):擴展的狀態(tài)碼,代表處理將被繼續(xù)執(zhí)行
3.2 狀態(tài)碼2xx:成功
- 200 OK:請求成功(其后是對GET和POST請求的應答文檔。)
- 201 Created:請求被創(chuàng)建完成,同時新的資源被創(chuàng)建。
- 202 Accepted:供處理的請求已被接受,但是處理未完成。
- 203 Non-authoritative Information:文檔已經正常地返回,但一些應答頭可能不正確,因為使用的是文檔的拷貝。
- 204 No Content:沒有新文檔。瀏覽器應該繼續(xù)顯示原來的文檔。如果用戶定期地刷新頁面,而Servlet可以確定用戶文檔足夠新,這個狀態(tài)代碼是很有用的。
- 205 Reset Content:沒有新文檔。但瀏覽器應該重置它所顯示的內容。用來強制瀏覽器清除表單輸入內容。
- 206 Partial Content:客戶發(fā)送了一個帶有Range頭的GET請求,服務器完成了它。
3.3 狀態(tài)碼3xx:重定向
- 300 Multiple Choices:多重選擇。鏈接列表。用戶可以選擇某鏈接到達目的地。最多允許五個地址。
- 301 Moved Permanently:所請求的頁面已經轉移至新的url
- 302 Found:所請求的頁面已經臨時轉移至新的url。
- 303 See Other:所請求的頁面可在別的url下被找到。
- 304 Not Modified:未按預期修改文檔。客戶端有緩沖的文檔并發(fā)出了一個條件性的請求(一般是提供If-Modified-Since頭表示客戶只想比指定日期更新的文檔)。服務器告訴客戶,原來緩沖的文檔還可以繼續(xù)使用。
- 305 Use Proxy:客戶請求的文檔應該通過Location頭所指明的代理服務器提取。
- 306 Unused:此代碼被用于前一版本。目前已不再使用,但是代碼依然被保留。
- 307 Temporary Redirect:被請求的頁面已經臨時移至新的url。
3.4 狀態(tài)碼4xx:客戶端錯誤
- 400 Bad Request:服務器未能理解請求。
- 401 Unauthorized:被請求的頁面需要用戶名和密碼。
- 401.1:登錄失敗。
- 401.2:服務器配置導致登錄失敗。
- 401.3:由于 ACL 對資源的限制而未獲得授權。
- 401.4:篩選器授權失敗。
- 401.5:ISAPI/CGI 應用程序授權失敗。
- 401.7:訪問被 Web 服務器上的 URL 授權策略拒絕。這個錯誤代碼為 IIS 6.0 所專用。
- 402 Payment Required:此代碼尚無法使用。
- 403 Forbidden:對被請求頁面的訪問被禁止。
- 404 Not Found: 服務器無法找到被請求的頁面。
- 405 Method Not Allowed: 請求中指定的方法不被允許。
- 406 Not Acceptable: 服務器生成的響應無法被客戶端所接受。
- 407 Proxy Authentication Required: 用戶必須首先使用代理服務器進行驗證,這樣請求才會被處理。
- 408 Request Timeout: 請求超出了服務器的等待時間。
- 409 Conflict: 由于沖突,請求無法被完成。
- 410 Gone: 被請求的頁面不可用。
- 411 Length Required: "Content-Length" 未被定義。如果無此內容,服務器不會接受請求。
- 412 Precondition Failed: 請求中的前提條件被服務器評估為失敗。
- 413 Request Entity Too Large: 由于所請求的實體的太大,服務器不會接受請求。
- 414 Request-url Too Long: 由于url太長,服務器不會接受請求。當post請求被轉換為帶有很長的查詢信息的get請求時,就會發(fā)生這種情況。
- 415 Unsupported Media Type: 由于媒介類型不被支持,服務器不會接受請求。
- 416 Requested Range Not Satisfiable: 服務器不能滿足客戶在請求中指定的Range頭。
- 417 Expectation Failed: 執(zhí)行失敗。
- 423: 鎖定的錯誤。
3.5 狀態(tài)碼5** 服務端錯誤
- 500 Internal Server Error:請求未完成。服務器遇到不可預知的情況。
- 501 Not Implemented:請求未完成。服務器不支持所請求的功能。
- 502 Bad Gateway:請求未完成。服務器從上游服務器收到一個無效的響應。
- 503 Service Unavailable:請求未完成。服務器臨時過載或當機。
- 504 Gateway Timeout:網關超時。
- 505 HTTP Version Not Supported:服務器不支持請求中指明的HTTP協(xié)議版本。
總結
以上是生活随笔為你收集整理的我终于知道post和get的区别的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 阅读源码学设计模式-单例模式
- 下一篇: 【译】使用Blazor构建桌面应用