HTTP

HTTP 請求方法 — HEAD、PUT、DELETE

HEAD

與 GET 方法相同,但 Server 只傳輸 狀態行 以及 表頭部分
Same as GET, but (Server) only transfer the status line and header section.

 
HEAD 與 GET 方法相同,但 Server 不得 於回應中,傳輸 訊息主體 (message body)
 
Server 在回應中,應傳輸 與 GET 請求 相同的 表頭,
除了 (3-4) 酬載表頭欄位 (payload header fields) 可能被省略。
 
該方法可被用在 不傳送 表示 的實際資料 的情況下,
獲得關於所選擇的 表示 (representation) 的 元資料 (metadata)
通常用於測試超文本鏈接的有效性,可訪問性和最近的修改。
 
與 GET 相同:

對於 HEAD 請求訊息,酬載 (payload) 是 未定義的語意,
在 HEAD 請求上發送 酬載,可能導致一些 Server 拒絕該請求

 
 

屬性 (property)

安全性: Yes
冪等性: Yes
可快取性: Yes
 
與 GET 相同,詳見 (4-1) 請求方法、安全性、冪等性(6-1) 快取 (Cache)
 


 

PUT

以請求的 酬載 (payload),替換 目標資源 所有目前的 表示 (representations)
Replace all current representations of the target resource with the request payload.

 
PUT 可想成是動詞的 置放置換
用一個超噁爛的例子說明就是 — — 麵包超人 (童年的惡夢…)。
 
以 新的頭 (請求的酬載) 置換 掉 原本的頭 (目標資源)…😑 ,
如果原本沒有頭,也沒關係 (新增):

 
很好,你應該已經理解了…吧 🙄,
講得更白話一點,就是 修改 or 更新 囉!
 
別忘了 HTTP 的 統一介面 (uniform interface) 架構約束,
擁有 技術異質性 (Technology Heterogeneity) [͵hɛtərədʒəˋniətɪ] ,
代表 Origin Server 能自行實作 資料儲存,HTTP 並沒有定義資源表示的種類、儲存方式。
 
DIP-electricity-ex

所有實作細節,皆隱藏在介面之後 — — 封裝隔離

 
需要注意的是,若想實現「部分」更新,
嚴禁使用 Content-Range 表頭欄位
而是使用 PATCH 請求方法 !
 
 

屬性 (property)

安全性: No
冪等性: Yes
可快取性: No
 
一成功的 PUT 請求,理想情形 下:

後續對於同一目標資源的 GET 請求,
Server 應發送 200 (ok) 或與之等價的 成功狀態碼。

 
然而,這只意味著 使用者代理 (User Agent) 的目的,在 當時 是成功被 源伺服器 (Origin Server) 處理的。
無法保證 目標資源 不會同時被 Servr 或 其他使用者操作,進而使 狀態產生變化 (state change)
 
這也代表 PUT 請求 可能帶來 副作用 (side effect)
例如,一個 URI 映射的資源語意為「最新版本的文章」,
若 PUT 請求成功替換該文章,可能導致 新增相關資源的連結 或 舊有文章消失。
 
 
因此,PUT 請求 的 回應是 不可快取的
若收到快取的 PUT 回應,需視為無效。
 
再次:

狀態的改變 (state change) 是 狀態傳輸/轉移 (state transfer)... 狀態的改變 (state change) 是 狀態傳輸/轉移 (state transfer)... 狀態的改變 (state change) 是 狀態傳輸/轉移 (state transfer)...

 
詳見 (4-1) 請求方法、安全性、冪等性(6-1) 快取 (Cache)
 
 

參數 與 表單 (parameter & form)

與 POST 相同,PUT 方法 將 參數 [pəˋræmətɚ]、資料 置放於 訊息主體 (message body) 中,
若 表單欄位 為帳號、密碼,使用 PUT 即不會出現於 URI 之中 😆,因此 相對 GET 表單 安全
(當然,也能同時使用 URI 的 query 部分)
 


使用 PUT 表單,與 POST 如出一轍,
需於 <form> 標籤的 method 屬性中設置 put:
 
↑如果這樣想,你就毀了!

 
 

HTTP vs. HTML

HTTP 中的標準化方法:

GET 、 POST 、 PUT 、 DELETE 、
HEAD 、 CONNECT 、 OPTIONS 、 TRACE

 
其中,HTML5 的 表單 (form) 僅支援 GETPOST 方法 !
若將表單的 method 屬性 改成 put,HTML5 會以預設的 GET 方法取代之:

Search:
(可測試 並觀察網址列 產生 變化 — — 代表為 GET 表單)
<form action="https://echo.paw.cloud" method="put">
  Search: <input type="search" name="search"> <input type="submit" value="Submit">
</form>

 
 
事實上,HTML5 的設計草案,曾一度支援 PUT、DELETE 表單
卻因種種因素刪除,詳情請見 Why are there are no PUT and DELETE methods on HTML forms?
 
這成為許多設計不良應用的藉口 (例如,URI 不應包含動詞):

https://echo.paw.cloud?page=3&action=put

 
儘管如此,幾乎所有 使用者代理 (User Agent) [e.g., 瀏覽器 (browser)],
都有支援 PUTDELETE 喔 !

表單 僅是 HTTP 請求 的一種使用。

 
 

方法欺騙 (Method Spoofing) — 不建議

所以,到底如何在不違背 HTTP 設計 (分離資源辨識 與 請求語意) 下,
送出 PUT、DELETE、PATCH… 請求呢?
 
一個常見的做法,稱為 — — 方法欺騙 (Method Spoofing)
 
聽起來很牛,實際上還是送出 POST 表單 啦 😂,
只是送出的資料中,夾帶一個「真正」要用的 方法名稱,
Server 在接收請求時,會先檢查此值,以決定如何操作表示。
 
通常是利用 <input> 標籤 hidden type 看不見的特性,
提供一個 隱藏的 _method 欄位,並在 value 屬性中 設置「真正」要用的 方法名稱,
另外,可別忘了預防 CSRF 攻擊

<form action="https://echo.paw.cloud" method="post">
    <input type="hidden" name="_method" value="PUT">
</form>

 
(與 POST 表單 「看起來」完全相同)
 
 

JavaScript

方法欺騙 (Method Spoofing) 雖然普遍,但並 不建議 !
 
PUT 是 冪等方法 (Idempotent Methods),代表:

當 Client 接收 回應前,若發生通訊錯誤,
能被自動地重複送出,並確保效果相同。

 
然而,POST 是 冪等方法 (Idempotent Methods),
仍有可能被 Server 實作 快取功能
應用 方法欺騙 (Method Spoofing) 可能帶來許多問題!
 
較佳的方法,通常是 使用 JavaScript 來處理請求 !
詳見 JavaScript 發送 HTTP 請求 — (I) XMLHttpRequest
以及 jQueryFetch API
 
 

回應 (response)

許多 (4-6) 回應狀態碼 都可能在 PUT 請求 的回應中被接收。
以下僅一些情境為例,不代表所有可能性:
 

新增

如果發送 PUT 請求 時,Server 目標資源 並沒有 目前的表示 (current representation)
則與 POST 相同,直接 新增,且 源伺服器 (Origin Server) 必須送出 201 (Created) 回應,通知使用者代理。
大概是這種感覺… :

 
與 POST 相同,應包含一個 Location 表頭欄位,指出建立的主要資源的 URI,
以及引用新資源時,描述請求狀態的 表示 (representation)。
 
 

修改

如果 (Server) 目標資源 確實具有 目前的表示,
並且 Server 根據 PUT 請求 所附之 表示 (representation) 的狀態,成功替換之,
則 源伺服器 必須發送 200 (OK)204 (No Content) 回應,指示成功完成 PUT (修改) 請求。
 
 

驗證內容

源伺服器 應該驗證 PUT 表示,是否與 Server 對目標資源的任何約束一致,
例如,Server 要你上傳圖片,你上傳個 SNIS-928.mp4 那就不對啦 !
 
upload-error
 
當 源伺服器 使用與 URI 相關的內部配置資訊,
以便為 GET 回應 中設置 表示元資料 時,這一點尤為重要。
(e.g., Content-Type、Content-Encoding)
 
PUT 表示 與目標資源不一致時,源伺服器 應藉由 轉換 該表示 或 更改資源配置 使其一致,
或者 使用包含足夠錯誤資訊的回應,解釋為什麼該 表示 不合適。 (e.g., 409 Conflict)
若是對於 Content-Type 的格式約束, 415 (Unsupported Media Type) — 不支援的媒體種類,會相當有用。
 


 

DELETE

移除 目標資源 所有目前的 表示 (representations)
Remove all current representations of the target resource.

 
DELETE 可直翻為動詞的 刪除移除
然而,HTTP 並沒有規範 DELETE 實作方式。
 
這代表,若目標資源擁有一或多個 表示 (representation)
刪除多少個、怎麼刪除 全仰賴 目標 URI、資源性質 與 源伺服器 的實作
因此不該想像成 UNIX 系統的 rm 刪除指令。
 
[註]:沒事千萬別手癢去終端機打 強制遞迴刪除指令,
多少公司就這樣毀了 😱 (身邊好多人手癢過…):

rm -rf

 
且基於安全性、一致性、可擴展性…等議題,
Server 可能以改變 資源游標 (cursor)、隱藏資源…等方式 假裝刪除
而非真的 刪除該表示 或 一個檔案、記錄。
 
 

屬性 (property)

安全性: No
冪等性: Yes
可快取性: No
 
詳見 (4-1) 請求方法、安全性、冪等性(6-1) 快取 (Cache)
 
 

參數 與 表單 (parameter & form)

與 GET 方法相同:

對於 DELETE 請求訊息,酬載 (payload) 是 未定義的語意,
在 DELETE 請求上發送 酬載,可能導致一些 Server 拒絕該請求

 
使用 DELETE方法,需提供額外的 參數 (parameter) [pəˋræmətɚ] 時,
大多以 鍵值對 (key-value) 的方式,置於 URI 的 查詢 (query) 部分,如:

https://echo.paw.cloud:443/hello/world?age=24&gender=female

 
但別忘了,HTML5 的 表單 (form) 僅支援 GETPOST 方法 !
若將表單的 method 屬性 改成 delete,HTML5 會以預設的 GET 方法取代之。
 
 

回應 (response)

部分 狀態碼 (Status Codes) 可能在 DELETE 請求 的回應中被接收。
以下僅一些情境為例,不代表所有可能性:
 

移除

如果 DELETE 方法成功被 源伺服器 應用:
若該操作可能成功,但尚未被執行 — — 202 (Accepted) 回應,
若該操作已成功,且無進一步資訊 — — 204 (No Content) 回應,
若該操作以成功,且回應訊息中包括描述資源狀態的 表示 (representation) — — 200 (OK) 回應。

 
 

作者: 鄭中勝
喜愛音樂,但不知為何總在打程式 ? 期許能重新審視、整理自身所學,幫助有需要的人。

在《HTTP 請求方法 — HEAD、PUT、DELETE》中有 3 則留言

發表迴響