HTTP Request Method 設計行為與分析 === ###### tags: `RESTful` 我們常見的請求方法有兩種「get」與「post」,在早期進行網頁開發的後端程式,對於get和post的處理方式基本上是相同的(php、jsp、asp),工程師時常將get與post這兩種請求方法混用。 隨著網頁開發的進步,我們逐漸擁抱非同步的網頁設計(ajax),這樣子的變化讓網頁在開發的過程中,必須設計更多的URL迎合在相同頁面中非同步的資源請求,通常我們傾向制定有一定規則的應用程式介面(API)進行接入。 事實上,HTTP在設計時,便有針對資源請求進行請求方法(Request Method)的規範,所有建立在HTTP協定上的伺服器,都必須能符合這些規範。 :::success :bookmark: **目錄** :::spoiler [TOC] ::: ## 標準化方法(standardized method) HTTP中定義了不同的請求方法(Request Method)。並且,HTTP其中的一個設計目標為 > 分離「資源辨識 (resource identification) 」與「請求語意(request semantics) 」。 > 其中的請求語意便是HTTP所定義的請求方法所要規範的部分。 而請求方法的設計含意便是: > 由客戶端(client)發出請求的目的(purpose)與期望伺服器(server)所回傳的結果 ### 規範 以下將常用的請求方法列出,並且大致闡述所代表的語意。 | Verb | SAFE | IDEMPOTENT | Cacheable |動作 |語意 | | -------- | -------- | -------- | -------- | -------- | -------- | | GET | O |O |O |讀取|請求所需要的資源。 | HEAD | O |O |O |讀取|與GET相同,但伺服器只傳輸HTML的狀態與表頭。 | POST | X |X|O |新增|在請求中攜帶負載,並執行特定資源的處理。 | PATCH | X |X|X |部分更新|請求更新一筆資源的部分內容,必須是存在的資源。 | PUT | X |O|X |完整更新|請求更新一筆資源的所有內容,必須是存在的資源,資源傳遞必須完整,否則為空。 | DELETE | X |O|x |刪除|請求移除資源。 ### 實作 我們以Blog中的文章操作為例。 | 路由(Route) |HTML動詞(Verb)| 描述(Description) | | -------- | -------- | -------- | | /api/article | GET | 獲取所有文章 | | /api/article/ | POST | 新增一筆文章 | | /api/article/:article_id | GET | 獲取一筆文章 | | /api/article/:article_id | PUT | 更新一筆文章 | | /api/article/:article_id | DELETE | 刪除一筆文章 | 使用後端程式實現上述路由,通過HTML所提供的請求方法與資料庫的CURD相呼應,制定出合乎規範的API。 ## 方法屬性(Method Properties) 在請求方法中,HTML設計Safe與Idempotent兩種特性。有時候,在設計API時,我們會拘泥於語意的含意,因為有些請求的並不是只有單純CURD的形式;而利用這兩種特性,便可以幫助我們去思考API究竟要用何種形式的請求方法較為恰當。 ### 安全方法 (Safe Methods) > GET、HEAD 為安全方法。 SAFE代表的含意為「是否安全」,所謂的安全便是「在請求的過程中,是否有任何資源的改動(新增、修改、移除)」。 合理的使用安全方法並不會對Server造成危害、資源損失或運作異常;然而,安全方法的定義僅僅是規範的標準,HTML的規範無法強制規定程式設計師使用請求方法的方式,若是使用具有危險因子的設計也會讓Server暴露在危險之中。 ### 非安全方法 (Unsafe Methods) >POST、PUT、DELETE 為非安全方法。 非安全方法並不是在「網頁資訊安全」上不安全,而是指這樣子的請求將會造成Server的狀態改變(State Change)。而區分安全方法與非安全方法是為了避免網頁爬蟲和網頁快取的執行下,誤觸了改變伺服器狀態的請求,造成並非我們所預見的結果。 ### 淺在危害實作 (Potentially Harmful Implementation) 再一次提到,雖然HTML在請求方法有完整的規範,但規範僅僅是規範,無法避免網頁工程師在開發中使用具有風險的實作。 例如: ``` Http://blog.com/artical/001?action=delete ``` 以上的範例所描述的行為是,以GET刪除某筆文章。這樣的實作違反了HTML的規範,即GET在請求的過程中,不能有資源的改變。以上的設計雖然在程式撰寫上方便,卻帶來了以下隱憂。 例如:Google Search 的爬蟲會遍歷網站所有的連結與頁面,若是以GET設計新增、修改、刪除等URL,將會造成Google的爬蟲程式造訪刪除的功能,造成網站資料誤刪的情形。 若是程式開發人員以DELETE實作刪除動作,網頁爬蟲程式將會自動略過請求,因為網頁爬蟲程式並不會造訪非安全方法下的任何請求。 ### 冪等方法 (Idempotent Methods) 若擁有這個特性,則代表這筆請求就算重複操作,也會產生相同的結果。換句話說,如果在網路狀態不佳的環境,就算重複執行也不會有問題。 > GET、HEAD、PUT、DELETE是IDEMPOTENT,代表不管重複幾次都是相同的請求。 > POST與PATCH則「非」IDEMPOTENT。POST再執行一遍便會重新新增一筆資料。PATCH則是不保證重複新增資料的可能性,比如說:更新modified time。 而區分兩種方法的目的在於,當客戶端接收回應前如果發生錯誤,無法確認請求是否被伺服器正確執行的情況下。符合冪等方法規則的請求能夠重複送出,並且有相同的結果。 ### 可快取方法 (Cacheable Methods) > GET、HEAD、POST為可快取方法 可快取方法代表可允許客戶端將內容保存下來,在未來重複造訪網站時可以重複利用,減少請求回應的時間,降低伺服器在處理頁面時的寬頻消耗,增加網頁運作效能。 例如:網頁加載所需的CSS、js、img等檔案以GET傳輸,客戶端將會保存這些內容,加快二次造訪時頁面的顯示速度。 但在絕大部分的實作中,可快取方法只在GET與HEAD中實現。 ## 參考資料 https://notfalse.net/43/http-request-method#-Method-Properties https://data-sci.info/2015/10/24/%E5%B8%B8%E8%A6%8B%E7%9A%84http-method%E7%9A%84%E4%B8%8D%E5%90%8C%E6%80%A7%E8%B3%AA%E5%88%86%E6%9E%90%EF%BC%9Agetpost%E5%92%8C%E5%85%B6%E4%BB%964%E7%A8%AEmethod%E7%9A%84%E5%B7%AE%E5%88%A5/ https://developer.mozilla.org/zh-TW/docs/Web/HTTP/Methods https://ihower.tw/blog/archives/6483
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up