1. 程式人生 > >表單提交時編碼類型enctype詳解

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

表單提交 這不 algo inter 轉義 除了 如果 ctype target

很早以前,當還沒有前端這個概念的時候,我在寫表單提交完全不去理會表單數據的編碼,在action屬性裏寫好目標URL,剩下的啊交給瀏覽器吧~但是現在,更多時候我們都采用Ajax方式提交數據,這種原始的方式僅僅被當成優雅降級的產物。

當我們用異步方式提交表單,就需要稍微關註一下表單數據的編碼問題了。回想一下,在寫回調函數時是不是有根據過請求的Content-Type寫不同業務邏輯的經歷,那這個Content-Type和表單的編碼有什麽聯系嗎?有沒有在明明前端已經發數據給後端了,後端的小夥伴死活取不到數據的情況?這些糾結的問題背後的原因真是困擾了我好久,今天在篇文章裏就要把它們掰扯清楚!

是什麽決定了表單的編碼?

熟悉表單元素<form>的小夥伴,對其中的屬性enctype一定不會陌生,就是它規定了對表單提交給服務器時表單數據編碼的內容類型(Content Type)。以下引用,摘自HTML 4.01規範的Form章節:

enctype = content-type [CI]
This attribute specifies the content type used to submit the form to the server

content type?這不就是我們在回調函數裏判斷返回數據的類型,並且是在請求頭中的那個玩意兒嗎?!沒錯!就是它!根據HTML 4.01規範的基礎數據類型的說明,這個content type指定了連接資源的屬性

,同時也是MIME type的那些媒體類型。

表單編碼類型

知道了表單編碼由enctype決定的,那麽它究竟有多少可選的取值呢?是不是所有的MIME類型它都能用呢?
實際上,根據HTML5 規範中所敘述的,enctype具有以下三種選項,其中最後一項text/plain是相比4.01新增的。

  • application/x-www-form-urlencoded

  • multipart/form-data

  • 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提交表單的類型吧。

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