http請求方法
請求方法的含義
- GET
The GET method requests a representation of the specified resource. Requests using GET should only retrieve data.
get方法請求指定的資源.get請求應該僅僅用去獲取數(shù)據
HEAD
The HEAD method asks for a response identical to that of a GET request, but without the response body.
head方法期望得到與get方法相同的響應仅叫,但響應體
POST
The POST method is used to submit an entity to the specified resource, often causing a change in state or side effects on the server
post方法用于將實體提交給指定的資源,通常會導致服務器上狀態(tài)的改變,或產生副作用御滩。
PUT
The PUT method replaces all current representations of the target resource with the request payload.
put使用有效的請求去替換目標資源的當前狀態(tài)(用客戶端發(fā)送的數(shù)據去替換服務器端的數(shù)據)
put方法用
DELETE
The DELETE method deletes the specified resource.
delete方法用于刪除指定的資源
CONNECT
The CONNECT method establishes a tunnel to the server identified by the target resource.
connect方法建立起由目標資源標識到服務器端的隧道
OPTIONS
The OPTIONS method is used to describe the communication options for the target resource.
options方法用于描述目標資源的通信選項。
TRACE
The TRACE method performs a message loop-back test along the path to the target resource.
trace方法沿著目標資源的路徑執(zhí)行消息環(huán)回測試。
PATCH
The PATCH method is used to apply partial modifications to a resource.
patch方法用于對資源進行部分修改梯啤。
這里著重強調一下我們比較常用的get方法和post方法的區(qū)別
含義
get:用于向服務器請求資源
post:向服務器發(fā)送實體數(shù)據傳遞數(shù)據的方式不同(當傳遞數(shù)據時)
get:將數(shù)據連接在url地址后面通過?進行分隔
post:將數(shù)據放在請求體中效率
get 更簡單也更快安全性
由于get方法將發(fā)送給服務器的信息直接加載url之后,相比post的將信息放在http報文主體上便顯得更加不安全緩存
get請求默認會被緩存存哲,默認的請求方式也是有緩存的因宇,所以我們在用get方法請求同一資源的時候如果希望每次請求的資源都是從服務器端獲取的最新資源而不是緩存的資源時,往往會通過在url后面加上&rand=Math.random()
使得每次發(fā)送的url地址不完全相同來保證能每次都從服務器上獲取資源
post由于post方法主要是為了向服務器傳送數(shù)據祟偷,雖然對同一資源傳遞數(shù)據時url每次都相同察滑,但是http報文的請求體中的數(shù)據往往不相同,所以緩存也沒什么用修肠,所以瀏覽器一般默認不緩存除非主動去設置數(shù)據發(fā)送量
get請求對發(fā)送的數(shù)據量會有限制
post請求對發(fā)送的數(shù)據量往往不會有太大限制
對于請求方式的知識贺辰,通過以上的小結,或許你覺得自己已經了解得差不多了嵌施,那么問題來了饲化?
- get請求為什么會比post請求更快呢?
- 能否把get請求都換成post吗伤?把post換成get呢吃靠?
是否陷入了沉思?是的足淆,前面的那點點知識還不夠用巢块,讓我們接著往后看~
其實GET和POST本質上并沒有什么區(qū)別礁阁。
get和post僅僅知識http協(xié)議中的兩種請求方法,而http是基于TCP/IP的關于數(shù)據如何在萬維網中如何通信的協(xié)議族奢。
HTTP的底層是TCP/IP姥闭。所以GET和POST的底層也是TCP/IP,也就是說歹鱼,GET/POST都是TCP鏈接泣栈。GET和POST能做的事情是一樣一樣的。你要給GET加上request body弥姻,給POST帶上url參數(shù),技術上是完全行的通的掺涛。
那么庭敦,“為什么會出現(xiàn)前面那些,我們自以為是的“正確答案”呢薪缆?
在萬維網世界中秧廉,TCP就像汽車,我們用TCP來運輸數(shù)據拣帽,它很可靠疼电,從來不會發(fā)生丟件少件的現(xiàn)象。但是如果路上跑的全是看起來一模一樣的汽車减拭,那這個世界看起來是一團混亂蔽豺,送急件的汽車可能被前面滿載貨物的汽車攔堵在路上,整個交通系統(tǒng)一定會癱瘓拧粪。為了避免這種情況發(fā)生修陡,交通規(guī)則HTTP誕生了。HTTP給汽車運輸設定了好幾個服務類別可霎,有GET, POST, PUT, DELETE等等魄鸦,HTTP規(guī)定,當執(zhí)行GET請求的時候癣朗,要給汽車貼上GET的標簽(設置method為GET)拾因,而且要求把傳送的數(shù)據放在車頂上(url中)以方便記錄。如果是POST請求旷余,就要在車上貼上POST的標簽绢记,并把貨物放在車廂里。當然荣暮,你也可以在GET的時候往車廂內偷偷藏點貨物庭惜,但是這是很不光彩;也可以在POST的時候在車頂上也放一些數(shù)據穗酥,讓人覺得傻乎乎的护赊。HTTP只是個行為準則惠遏,而TCP才是GET和POST怎么實現(xiàn)的基本。
但是骏啰,我們只看到HTTP對GET和POST參數(shù)的傳送渠道(url還是requrest body)提出了要求节吮。“標準答案”里關于參數(shù)大小的限制又是從哪來的呢判耕?
在我大萬維網世界中透绩,還有另一個重要的角色:運輸公司。不同的瀏覽器(發(fā)起http請求)和服務器(接受http請求)就是不同的運輸公司壁熄。 雖然理論上帚豪,你可以在車頂上無限的堆貨物(url中無限加參數(shù))。但是運輸公司可不傻草丧,裝貨和卸貨也是有很大成本的狸臣,他們會限制單次運輸量來控制風險,數(shù)據量太大對瀏覽器和服務器都是很大負擔昌执。業(yè)界不成文的規(guī)定是烛亦,(大多數(shù))瀏覽器通常都會限制url長度在2K個字節(jié),而(大多數(shù))服務器最多處理64K大小的url懂拾。超過的部分煤禽,恕不處理。如果你用GET服務岖赋,在request body偷偷藏了數(shù)據檬果,不同服務器的處理方式也是不同的,有些服務器會幫你卸貨贾节,讀出數(shù)據汁汗,有些服務器直接忽略,所以栗涂,雖然GET可以帶request body知牌,也不能保證一定能被接收到哦。
好了斤程,現(xiàn)在你知道角寸,GET和POST本質上就是TCP鏈接,并無差別忿墅。但是由于HTTP的規(guī)定和瀏覽器/服務器的限制扁藕,導致他們在應用過程中體現(xiàn)出一些不同。
GET和POST的區(qū)別????????
GET和POST還有一個重大區(qū)別疚脐,簡單的說:
GET產生一個TCP數(shù)據包亿柑;POST產生兩個TCP數(shù)據包。
長的說:
對于GET方式的請求棍弄,瀏覽器會把http header和data一并發(fā)送出去望薄,服務器響應200(返回數(shù)據)疟游;
而對于POST,瀏覽器先發(fā)送header痕支,服務器響應100 continue颁虐,瀏覽器再發(fā)送data,服務器響應200 ok(返回數(shù)據)卧须。
也就是說另绩,GET只需要汽車跑一趟就把貨送到了,而POST得跑兩趟花嘶,第一趟笋籽,先去和服務器打個招呼“嗨,我等下要送一批貨來椭员,你們打開門迎接我”干签,然后再回頭把貨送過去。
因為POST需要兩步拆撼,時間上消耗的要多一點,看起來GET比POST更有效喘沿。因此Yahoo團隊有推薦用GET替換POST來優(yōu)化網站性能闸度。但這是一個坑!跳入需謹慎蚜印。為什么莺禁?
- GET與POST都有自己的語義,不能隨便混用窄赋。
- 據研究哟冬,在網絡環(huán)境好的情況下,發(fā)一次包的時間和發(fā)兩次包的時間差別基本可以無視忆绰。而在網絡環(huán)境差的情況下浩峡,兩次包的TCP在驗證數(shù)據包完整性上,有非常大的優(yōu)點错敢。
- 并不是所有瀏覽器都會在POST中發(fā)送兩次包翰灾,F(xiàn)irefox就只發(fā)送一次。
在深入的了解了http協(xié)議的兩種請求方法之后我想稚茅,讓我們在來回顧一次前面的問題
- get請求為什么會比post請求更快呢纸淮?
準確的說是多數(shù)情況下比較快,關鍵還是得看我們的瀏覽器大哥喜歡怎么做亚享。對于大多數(shù)瀏覽器來說由于get請求一次性將header和data一起發(fā)送即只發(fā)送一次包咽块,而post發(fā)送兩次數(shù)據包,第一次發(fā)送header欺税,等服務器返回100 continue后在發(fā)送第二次數(shù)據包侈沪,將data發(fā)送給服務器揭璃。一次發(fā)送跟兩次發(fā)送,很明顯get會更加效率一些峭竣。 - 能否把get請求都換成post塘辅?把post換成get呢?
我的答案是萬萬不能皆撩。
萬事萬物的存在的原因扣墩。對于http協(xié)議上的get和post方法更是如此,沒有人會無聊到能用一個方法就實現(xiàn)的東西偏偏要弄出兩種方法來讓其更加復雜扛吞。而我們想理解背后的原因呻惕,我覺得最好的方法便是結合實際的應用場景(畢竟http協(xié)議的產生的目的說到底還是為了更好的解決現(xiàn)實問題)
場景:
----------------摘自《圖解HTTP》
對于get請求,我們從文章開頭的定義中知道滥比,其目的僅僅是為了獲取資源亚脆,并不是為了傳送數(shù)據,所以即使要傳送數(shù)據盲泛,也要將數(shù)據放在了get請求的url后面濒持,而服務器對其的處理更是直接從url上直接解析,以了解用戶需要的資源寺滚,再決定是否將資源傳給用戶柑营。針對以上的描述,我們不難知道其實對于get請求確實只發(fā)送一次包就足夠了村视,發(fā)送兩次包實毫無意義的官套。
而對于post請求,其最主要的目的是為了向服務器發(fā)送數(shù)據蚁孔,并引起服務器端數(shù)據或狀態(tài)的某些改變奶赔。服務器在接到數(shù)據并處理之后返回處理后的結果給客戶端。現(xiàn)在讓我們結合上面的圖來思考一種情況杠氢,如果說客戶端指定的資源的訪問和修改是需要進行認證的站刑。而我們的post請求不是發(fā)送兩次包,一次發(fā)送頭部修然,一次發(fā)送data笛钝,會是發(fā)生什么?----瀏覽器一次性將header和data一起發(fā)送愕宋,而服務器卻因為該用戶還沒進行認證或者是不具備訪問權限玻靡,而不能接收用戶的數(shù)據進行處理,這樣的話豈不是浪費的大量的網絡資源中贝,但是如果是兩次發(fā)送就不同了囤捻,當?shù)谝粋€包發(fā)送的時候,服務器經過檢驗知道用戶具有訪問響應資源的權限邻寿,發(fā)送響應報文將頭部設為100 continue蝎土,讓瀏覽器發(fā)送后續(xù)的data视哑,而如果是還沒認證便發(fā)送401 Unauthorized讓用戶進行先認證,認證成功后才讓瀏覽器發(fā)送數(shù)據誊涯,這樣是便很好的解決了前面說提到的問題挡毅。
前兩張圖是我分別通過post方法和get方法分別進行數(shù)據的發(fā)送后從瀏覽器中看到的, 可見暴构,瀏覽器對于get和post發(fā)送數(shù)據的處理方式并不相同跪呈,從而也開始懷疑瀏覽器在發(fā)送get請求的時候是否真的會將沒有數(shù)據的body也發(fā)送了,便通過以下代碼進行了嘗試
$(function (){ $("#myform").on('submit',function (event){ event.preventDefault(); var data = $(this).serialize(); /* $.ajax({ method:"POST", url:"/mytest", data:data }) .done(function (msg){ console.log(msg); });*/ var xhr = new XMLHttpRequest(); // var url = "/mytest?"+data; var url = "/mytest"; xhr.open("post",url,true); xhr.onreadystatechange = function (){ if (xhr.readyState == 4) { if (xhr.status == 200) { console.log(xhr.responseText); } } }; xhr.send("test=i am a test"); }); });
于是有了圖三取逾,圖四耗绿,兩張圖分別是改動open方法中的第一個參數(shù)分別為get和post,由于post方法的數(shù)據是放在body上的從圖四中我們可以認為request payload 代表的就是body砾隅,而get方法在url沒有接數(shù)據的時候沒有query string paramters 也沒有request payload误阻,那么如果我們將body與request payload等同的話,則可以認為get方法發(fā)送請求時報文并沒有發(fā)送body晴埂,另外從w3c收到關于body的介紹
4.3 Message Body The message-body (if any)of an HTTP message is used to carry the entity-body associated with the request or response. The message-body differs from the entity-body only when a transfer-coding has been applied, as indicated by the Transfer-Encoding header field (section 14.41).
注意到其中的if any便可知道究反,http請求其實是可以沒有body的,所以完全有理由相信get方法發(fā)送請求時甚至都不發(fā)送body儒洛。
綜上奴紧,我們可以知道,其實get和post都有其存在的必要信晶丘,雖然只有其中的一個我們依舊可以實現(xiàn)獲取資源,發(fā)送數(shù)據的最終目的唐含,但是為了更好的利用網絡資源浅浮,區(qū)分出get和post方法時真的非常有必要的