很早之前,當尚未前端這個概念的時候,我在寫表單提交徹底不去理會表單數據的編碼,在action
屬性裏寫好目標URL,剩下的啊交給瀏覽器吧~可是如今,更多時候咱們都採用Ajax方式提交數據,這種原始的方式僅僅被當成優雅降級的產物。html
當咱們用異步方式提交表單,就須要稍微關注一下表單數據的編碼問題了。回想一下,在寫回調函數時是否是有根據過請求的Content-Type
寫不一樣業務邏輯的經歷,那這個Content-Type
和表單的編碼有什麼聯繫嗎?有沒有在明明前端已經發數據給後端了,後端的小夥伴死活取不到數據的狀況?這些糾結的問題背後的緣由真是困擾了我很久,今天在篇文章裏就要把它們掰扯清楚!前端
熟悉表單元素<form>
的小夥伴,對其中的屬性enctype
必定不會陌生,就是它規定了對錶單提交給服務器時表單數據編碼的內容類型(Content Type)。如下引用,摘自HTML 4.01規範的Form章節:html5
enctype = content-type [CI]
This attribute specifies the content type used to submit the form to the serverjson
content type?這不就是咱們在回調函數裏判斷返回數據的類型,而且是在請求頭中的那個玩意兒嗎?!沒錯!就是它!根據HTML 4.01規範的基礎數據類型的說明,這個content type指定了鏈接資源的屬性,同時也是MIME type的那些媒體類型。後端
知道了表單編碼由enctype
決定的,那麼它究竟有多少可選的取值呢?是否是全部的MIME類型它都能用呢?
實際上,根據HTML5 規範中所敘述的,enctype
具備如下三種選項,其中最後一項text/plain
是相比4.01新增的。瀏覽器
application/x-www-form-urlencoded服務器
multipart/form-dataapp
text/plain異步
這是默認的編碼類型,使用該類型時,會將表單數據中非字母數字的字符轉換成轉義字符,如"%HH",而後組合成這種形式key1=value1&key2=value2
;因此後端在取數據後,要進行解碼。函數
注意:
若表單中有文件,則只留文件名;
該類型用於高效傳輸文件、非ASCII數據和二進制數據,將表單數據逐項地分紅不一樣的部分,用指定的分割符分割每一部分。每一部分都擁有Content-Disposition
頭部,指定了該表單項的鍵名和一些其餘信息;而且每一部分都有可選的Content-Type
,不特殊指定就爲text/plain
。下面給出一個採用multipart/form-data
編碼類型的例子:
Content-Type: multipart/form-data; boundary=AaB03x
--AaB03x Content-Disposition: form-data; name="submit-name" Larry --AaB03x Content-Disposition: form-data; name="files"; filename="file1.txt" Content-Type: text/plain ... contents of file1.txt ... --AaB03x--
注意:
通常來講,method
和enctype
是兩個不一樣的互不影響的屬性,但在傳文件時,method
必需要指定爲POST
,不然文件只剩下filename了;
當沒有傳文件時,enctype
會改回默認的application/x-www-form-urlencoded
。
按照鍵值對排列表單數據key1=value1\r\nkey2=value2
,不進行轉義。
注意:
若表單中有文件,則只留文件名;
另外,還須要說明表單數據編碼類型application/json
,已經被W3C遺棄(詳見HTML JSON Form Submission),建議不要在<form enctype="...">
中使用了,即便用了若是瀏覽器不支持,也會替換成application/x-www-form-urlencoded
。
同理,其他的MIME類型,也不支持,均會替換成默認編碼application/x-www-form-urlencoded
。
PS:貌似如今瀏覽器都不支持了,我先用了下面幾個瀏覽器:
FF43:Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:43.0) Gecko/20100101 Firefox/43.0
Chrome49, Safari9.1:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36
IE6, 8
因此,enctype
能夠認爲就是表單數據的content type(MIME type)
,只不過其取值不能用除了上面提到的三個,不然會轉換成默認的編碼。
今天掰扯完了表單提交時的編碼類型enctype
,以及它和content type
、MIME type
的關係。下次再總結一下Ajax提交表單的類型吧。