異世界


2018年8月18日 星期六

HTTP METHOD的不同性質分析:GET,POST和其他4種METHOD的差別

一篇文章解釋HTTP Method

轉貼網址:http://mikuweb.blogspot.tw/2015/10/http-methodgetpost4method.html

HTTP協定中定義了多種不同的method,瀏覽器或是其他程式再進行HTTP連線時,會使用這些method來進行連線並取得回復。
這些method到底有甚麼差別呢?

這裡列舉常見的六種HTTP Method分別是head,get,post,delete,put,patch。
其實還有很多其他得Method,為甚麼要特別提到這六種呢?因為這六種跟網頁的資料有非常大的關係。

先從最常見的get和post說起吧。
一個剛接觸網頁的人或是早期用PHP寫網頁的人常常混用get和post,因為兩者的功能基本上是相同的,而且以前主流是使用網址的Query String和不同的URL來區分功能(比如上傳和搜尋),但是現在愈來愈多網頁用API導向,也就是一個URL負責一個「業務」,對於上傳和瀏覽分別用不同的Method來處理。

舉例來說,我們現在有一個可以留言的留言板,我們通常會使用get來取得現在的留言,而要新增新的留言時,我們會post到這個位置(有點像是問服務生今天的菜單,然後跟同一個服務生點餐)。一些比較早期的網頁則可能混用get和post,把瀏覽留言和新增留言放在不同網址(有點像把領錢和存錢規劃在不同櫃台辦理)。

所以我們現在知道,不同的Method就是對同一件事情做不同的操作。
再來舉服務生點餐的例子,
假設現在我們要點餐,我們必須先知道菜單是甚麼(get),
我們會向服務生點餐(post),
我們想要取消剛才點的餐點(delete),
我們想要重新點一次(put),
我們想要加點甜點和飲料(patch)。

到這裡我們已經提到了主要的Method了(head是取得get的http header而不取得內容,性質上我們可以當作跟get一樣),至於這幾種Method的行為我們可以統整一下:
head:和get一樣,只是head只會取的HTTP header的資料。
get:取得我們想要的資料。
post:新增一項資料。(如果存在會新增一個新的)
put:新增一項資料,如果存在就覆蓋過去。(還是只有一筆資料)。
patch:附加新的資料在已經存在的資料後面。(資料必須已經存在,patch會擴充這項資料)
delete:刪除資料。

說了這麼多,其實這些Method也只是HTTP建議我們這樣做而已,至於網站架設者是不是有遵守又是令外一回事了。(比如說他可以選擇用delete來新增留言)
不過,遵守規定是有好處的,因為瀏覽器會根據不同的Method做不同的事,Google的機器人也會根據連結的不同做不一樣的事(Google有一隻爬蟲會不停更新全世界的網站)。
舉一個例子,現在有一個行事曆網頁,有很多的行事曆事項,旁邊有修改和刪除的按鈕。
如果這些按鈕使用get,Google的爬蟲就會全部去按一遍(他想要知道你的網站的所有內容,他才能建立索引),然後我們的行事曆就被刪光光了!!
如果我們把刪除按鈕改成用delete,Google就不會去按了(他只會按get的連結)。

另外一個例子是,假設現在網路狀況不好,我們用網路ATM轉帳,傳送出去後卻因為網路不穩而瀏覽器沒收到回應,這時如果瀏覽器自動重新整理,就會送出兩筆轉帳要求!!
但是如果轉帳使用post,瀏覽器不但不會自動重新整理,甚至使用者要求重新整理時還會跳出警告訊息。

上面兩個例子告訴我們,不同的Method間接的告訴使用者應該怎麼樣操作這些動作。
這裡有兩個性質,Safe是是否安全,如果會修改資料就是不安全,間接說明是否可以快取(不重複發出請求);Idempotent則是是否可以在不確定有沒有成功送出時重新發出請求。
我們可以整理成以下表格:

image


我們發現,除了get之外的Method都會修改到資料,所以如果我們要寫一支爬蟲,我們就必須要注意,不可以輕易的去觸動除了get以外的Method,因為我們可能會無意間改到資料。
而get,put,delete都可以重新整理,是因為put會覆蓋掉原本的資料(跟服務生說「我」要吃牛排說10次還是只會來一份牛排),delete則是一定會清除資料(跟服務生說我不吃了),所以這3個Method都可以重複呼叫,所以當網路不穩定時瀏覽器可以被允許自動重新整理。

想想如果我們違反這些規定會有甚麼結果。
我們重複和服務生說「一份牛排」(POST)那結果將是我們點了很多份牛排。
我們重複和服務生說「加一份甜點」(patch)那結果就是很多份甜點。

我們架設網站和寫爬蟲時,如果可以儘量遵守這些協定,就可以避免不必要的麻煩。

沒有留言:

張貼留言