http post請求方式


1、HTML < form > 標簽的 enctype 屬性

定義和用法

enctype 屬性規定在發送到服務器之前應該如何對表單數據進行編碼。
默認地,表單數據會編碼為 "application/x-www-form-urlencoded"。
就是說,在發送到服務器之前,所有字符都會進行編碼(空格轉換為 "+" 加號,特殊符號轉換為 ASCII HEX 值)。

2、form表單在提交時:

1)先把form表單里的表單元素的name屬性和value屬性進行收集。
2)按照enctype屬性的設置,選擇合適的編碼方式,對數據進行編碼,放在請求頭里
3)瀏覽器進行發送。

3、application/x-www-form-urlencoded

這應該是最常見的 POST 提交數據的方式了。
瀏覽器的原生 < form > 表單,如果不設置 enctype 屬性,那么最終就會以 application/x-www-form-urlencoded 方式提交數據。

<form action="form_action.asp" enctype="text/plain">
  <p>First name: <input type="text" name="fname" /></p>
  <p>Last name: <input type="text" name="lname" /></p>
  <input type="submit" value="Submit" />
</form>

此時可以看到:

Content-Type: application/x-www-form-urlencoded;charset=utf-8
title=test&sub%5B%5D=1&sub%5B%5D=2&sub%5B%5D=3

首先,Content-Type 被指定為 application/x-www-form-urlencoded;
其次,提交的數據按照 key1=val1&key2=val2 的方式進行編碼,key 和 val 都進行了 URL 轉碼。
大部分服務端語言都對這種方式很好的支持,常用的如jQuery中的ajax請求,Content-Type 默認值都是application/x-www-form-urlencoded;charset=utf-8

1)它是post的默認格式,使用js中URLencode轉碼方法。
包括將name、value中的空格替換為加號;將非ascii字符做百分號編碼;將input的name、value用‘=’連接,不同的input之間用‘&’連接。
2)百分號編碼什么意思呢。
比如漢字‘丁’吧,他的utf8編碼在十六進制下是0xE4B881,占3個字節,把它轉成字符串‘E4B881’,變成了六個字節,每兩個字節前加上百分號前綴,得到字符串“%E4%B8%81”,變成九個ascii字符,占九個字節(十六進制下是0x244534254238253831)。
把這九個字節拼接到數據包里,這樣就可以傳輸“非ascii字符的  utf8編碼的 十六進制表示的 字符串的 百分號形式”,^_^。
3)同樣使用URLencode轉碼,這種post格式跟get的區別在於,get把轉換、拼接完的字符串用‘?’直接與表單的action連接作為URL使用,所以請求體里沒有數據;
而post把轉換、拼接后的字符串放在了請求體里,不會在瀏覽器的地址欄顯示,因而更安全一些。

4、multipart/form-data

這也是常見的post請求方式,一般用來上傳文件,各大服務器的支持也比較好。
所以我們使用表單 上傳文件 時,必須讓

表單的enctype屬性值為 multipart/form-data.

通過 form 表單提交文件操作如下:

<FORM method="POST" action="http://w.sohu.com/t2/upload.do" enctype="multipart/form-data">
    <INPUT type="text" name="city" value="Santa colo">
    <INPUT type="text" name="desc">
    <INPUT type="file" name="pic">
 </FORM>

瀏覽器將會發送以下數據:

POST /t2/upload.do HTTP/1.1
User-Agent: SOHUWapRebot
Accept-Language: zh-cn,zh;q=0.5
Accept-Charset: GBK,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Content-Length: 60408
Content-Type:multipart/form-data; boundary=ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC
Host: w.sohu.com

--ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC
Content-Disposition: form-data; name="city"

Santa colo
--ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC
Content-Disposition: form-data;name="desc"
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
 
...
--ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC
Content-Disposition: form-data;name="pic"; filename="photo.jpg"
Content-Type: application/octet-stream
Content-Transfer-Encoding: binary
 
... binary data of the jpg ...
--ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC--

從上面的 multipart/form-data 格式發送的請求的樣式來看,
它包含了多個 Parts,每個 Part 都包含頭信息部分,Part 頭信息中必須包含一個 Content-Disposition 頭,
其他的頭信息則為可選項, 比如 Content-Type 等。
Content-Disposition 包含了 type 和 一個名字為 name 的 parameter,
type 是 form-data,name 參數的值則為表單控件(也即 field)的名字,
如果是文件,那么還有一個 filename 參數,值就是文件名。
比如:

Content-Disposition: form-data; name="user"; filename="hello.txt"

上面的 “user” 就是表單中的控件的名字,后面的參數 filename 則是點選的文件名。
對於可選的 Content-Type(如果沒有的話),默認就是 text/plain。

注意:
如果文件內容是通過填充表單來獲得,
那么上傳的時候,Content-Type 會被自動設置(識別)成相應的格式,
如果沒法識別,那么就會被設置成 “application/octet-stream”
如果多個文件被填充成單個表單項,那么它們的請求格式則會是 multipart/mixed。
如果 Part 的內容跟默認的 encoding 方式不同,那么會有一個 "content-transfer-encoding" 頭信息來指定。

下面,我們填充兩個文件到一個表單項中,行程的請求信息如下:

Content-Type: multipart/form-data; boundary=AaB03x

--AaB03x
Content-Disposition: form-data; name="submit-name"

Larry
--AaB03x
Content-Disposition: form-data; name="files"
Content-Type: multipart/mixed; boundary=BbC04y

--BbC04y
Content-Disposition: file; filename="file1.txt"
Content-Type: text/plain

... contents of file1.txt ...
--BbC04y
Content-Disposition: file; filename="file2.gif"
Content-Type: image/gif
Content-Transfer-Encoding: binary

...contents of file2.gif...
--BbC04y--
--AaB03x--


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM