Form表單的主要Content-Type


  在Spa單頁面橫行的時代,前后端交互基本都是Json交互(也有通過FormData的,比如上傳文件)。而在之前的Jsp,Php前后不分家的時候,前后交互好大一部分都是通過Form表單來完成的。From標簽個屬性叫 enctype,這屬性指定了Form的Content-Type,可取的只有application/x-www-form-urlencoded, multipart/form-data, text/plain。

  而Content-Type包含3個部分:

  1.   media-type: 資源或數據的 MIME type (必填)
  2.   charset: 字符編碼標准
  3.   boundary: 對於多部分實體,boundary 是必需的,其包括來自一組字符的1到70個字符,已知通過電子郵件網關是非常健壯的,而不是以空白結尾。它用於封裝消息的多個部分的邊界

  application/x-www-form-urlencoded 是Form默認的Content-Type:表單提交時編碼必須遵循以下標准:

  1.   key和value都會被編碼。空格被替換為‘+’,保留字編碼對着參照 [RFC1738],非轉義字符被替換為‘’%hh‘’的格式(一個%和兩個代表示ASCII碼的16進制數字),換行被替換為‘%D0%0A’(對應CR LF),都可以通過encodeURI函數轉換,詳細還請查閱 mdn
  2.   key和value用‘=’來分隔,每一對key和value用‘&’來分隔

  比如:

 

  multipart/form-data 是用FormData來傳遞數據,和上邊的區別是,FormData用來傳遞大數據(非ascii字符和二進制數據),具體請參考另一篇文章 post使用form-data和x-www-form-urlencoded的本質區別 (這篇博客講的感覺很詳細了),編碼規則如下:

  1.   包含一個Content-Disposition字段,值為form-data
  2.         一個name屬行,值為對應表單key的name字段
  3.         所有的Mime傳輸一樣,用CR LF(‘%0D%0A’)來分隔數據

  比如:划線處為規則3

 

  接下我詳細說下multipart/form-data編碼,假設我們有以下Form

<FORM action="http://server.com/cgi/handle"
       enctype="multipart/form-data"
       method="post">
   <P>
   What is your name? <INPUT type="text" name="submit-name"><BR>
   What files are you sending? <INPUT type="file" name="files"><BR>
   <INPUT type="submit" value="Send"> <INPUT type="reset">
</FORM>

  當用戶輸入‘Larry’在文本input中,還選擇了一個文本文件‘file1.txt’,然后點擊提交按鈕,傳向后台的body體為:

  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--

  我們看到藍色部分,就是Content-Type,參考上上邊提到的,少了charset,多了個boundary(我們知道,在application/x-www-form-urlencoded 中是用‘&’來告訴服務器每一個key和value,比如一個get請求: http://localhost:8080/api?name=John&age=12 ,那么在multipart/form-data我們怎么告訴服務器呢,答案就是boundary,有了這個字段,服務器就知道一個value是從哪里開始和到哪里結束,這個字段開發者是不用寫的,瀏覽器會自動加上,網上說我們也可以自行設置,比如你可以設置你喜歡的字符,但是我沒有成功,每次都是隨機的給分配一個,測試如下:)

  

  回到剛才的Form表單,如果用戶選擇了第二個文件‘file2.gif’,傳輸結構會是以下:

   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