表單提交時編碼類型enctype詳解

很早之前,當尚未前端這個概念的時候,我在寫表單提交徹底不去理會表單數據的編碼,在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異步

application/x-www-form-urlencoded

這是默認的編碼類型,使用該類型時,會將表單數據中非字母數字的字符轉換成轉義字符,如"%HH",而後組合成這種形式key1=value1&key2=value2;因此後端在取數據後,要進行解碼函數

注意:

  • 若表單中有文件,則只留文件名;

multipart/form-data

該類型用於高效傳輸文件、非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-- 

注意:

  • 通常來講,methodenctype是兩個不一樣的互不影響的屬性,但在傳文件時,method必需要指定爲POST,不然文件只剩下filename了;

  • 當沒有傳文件時,enctype會改回默認的application/x-www-form-urlencoded

text/plain

按照鍵值對排列表單數據key1=value1\r\nkey2=value2,不進行轉義。

注意:

  • 若表單中有文件,則只留文件名;

application/json及其餘MIME類型

另外,還須要說明表單數據編碼類型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 typeMIME type的關係。下次再總結一下Ajax提交表單的類型吧。

相關文章
相關標籤/搜索