HTTP 請求時傳遞多部分表單數據(multipart/form-data)
--data-raw $'------demo11111\r\nContent-Disposition: form-data; name="Filedata"; filename="截屏2025-02-27 15.45.46.png"\r\nContent-Type: image/png\r\n\r\n\r\n------demo11111\r\nContent-Disposition: form-data; name="type"\r\n\r\n5\r\n------demo11111--\r\n'
--data-raw
選項用于直接傳遞原始數據,而多部分表單數據格式通常用于上傳文件或提交包含多種類型數據的表單
特殊符號解釋
$
在 Bash 等 shell 中,$'...'
是一種 ANSI C 引號字符串的語法。這種語法允許在字符串中使用 C 風格的轉義序列,比如 \r
(回車符)、\n
(換行符)、\t
(制表符)等。例如,$'\r\n'
會被解釋為回車換行符,這在多部分表單數據中是必要的,因為它遵循嚴格的換行格式要求。
\r\n
\r\n
是回車換行符,在 HTTP 協議和多部分表單數據中,它用于分隔不同的部分和字段。回車換行符是多部分表單數據格式的重要組成部分,用于明確每個字段和數據塊的邊界。
多部分表單數據結構分析
多部分表單數據由多個部分組成,每個部分之間用分隔符(這里是 ------demo11111
)分隔,每個部分包含以下內容:
分隔符:用于區分不同的表單字段或文件
內容描述頭:包含字段名、文件名、內容類型等信息
空行:由 \r\n
表示,用于分隔內容描述頭和實際數據
數據內容:實際要上傳的數據。
示例拆解
------demo11111
Content-Disposition: form-data; name="Filedata"; filename="截屏2025-02-27 15.45.46.png"
Content-Type: image/png<文件內容>
------demo11111
Content-Disposition: form-data; name="type"5
------demo11111--
第一部分:上傳一個名為 截屏2025-02-27 15.45.46.png 的 PNG 圖片,字段名為 Filedata
第二部分:上傳一個名為 type 的字段,值為 5
結束標記:最后以 ------demo11111-- 表示表單數據結束
示例
假設要向 http://example.com/upload 發送上述多部分表單數據,完整的 curl 命令可能如下:
curl -X POST \--data-raw $'------demo11111\r\nContent-Disposition: form-data; name="Filedata"; filename="截屏2025-02-27 15.45.46.png"\r\nContent-Type: image/png\r\n\r\n<文件內容>\r\n------demo11111\r\nContent-Disposition: form-data; name="type"\r\n\r\n5\r\n------demo11111--\r\n' \http://example.com/upload
這樣,curl 就會將多部分表單數據發送到指定的服務器地址
demo11111 是通用的嗎?
并不是通用的
在使用多部分表單數據(multipart/form-data)進行文件上傳或表單提交時,需要一個邊界字符串(boundary string)來分隔不同的表單字段或文件數據。這個邊界字符串是隨機生成的,目的是確保它不會在表單數據中意外出現,從而避免混淆不同的部分。
不同的客戶端(如瀏覽器、curl 等工具)在發起請求時,都會生成自己唯一的邊界字符串。例如,在 Chrome 瀏覽器中,當使用 HTML 表單上傳文件時,瀏覽器會自動生成一個邊界字符串;使用 curl 時,如果手動指定多部分表單數據,也需要提供一個邊界字符串,或者讓 curl 自動生成。
非通用性原因
唯一性要求:為了準確區分多部分表單數據中的各個部分,邊界字符串必須是唯一的。如果使用通用的邊界字符串,那么在數據中就有可能意外出現與邊界字符串相同的內容,導致服務器無法正確解析表單數據。
隨機生成機制:不同的請求在不同的時間、不同的客戶端發起,每次都會生成不同的邊界字符串。例如,你在兩次不同的 curl 請求中,生成的邊界字符串大概率是不一樣的。
bash
curl -X POST \--data-raw $'------WebKitFormBoundaryabc123\r\nContent-Disposition: form-data; name="Filedata"; filename="test.png"\r\nContent-Type: image/png\r\n\r\n<文件內容>\r\n------WebKitFormBoundaryabc123--\r\n' \http://example.com/upload
示例 2
curl -X POST \--data-raw $'------WebKitFormBoundaryxyz789\r\nContent-Disposition: form-data; name="Filedata"; filename="test2.png"\r\nContent-Type: image/png\r\n\r\n<文件內容>\r\n------WebKitFormBoundaryxyz789--\r\n' \http://example.com/upload