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

  

原文地址:https://www.cnblogs.com/hanshuai/p/11210803.html