表单内容类型(Form content types)

NOTES
本文原文为: https://www.w3.org/TR/html401...
翻译由 本人(赤石俊哉) 整理,若您是原作者并认为此文涉及版权侵犯,我会配合删除。

在 HTML 标签中,form 元素的 enctype 属性指定了用何种方式来编码提交到服务器的表单主体内容。用户代理必须支持以下列出的内容类型,但是不关心其他类型的表现。

也可以查看这一部分:escaping ampersands in URI attribute values

application/x-www-form-urlencoded

这是默认的内容类型。使用此类型的被提交的表单必须被编码成如下:

  1. 控件名称和值需要被转义,空格字符替换为 +,然后保留的字符根据[RFC1738]的第二部分,非字母数字字符用 %HH 替换。一个百分号和两位用于表示该字符ASCII码的十六进制数码。换行符用 CR LF 对代替,也就是 %0D%0A

  2. 控件名称和值的对按照他们在文档中出现的顺序进行排列。名称和值之间用 = 分隔。每个名称和值的对之间用 & 分隔。

multipart/form-data

NOTES
请参照[RFC2388]以了解更多关于文件上传的信息,包括逆向兼容性问题,其他类型和 multipart/form-data 之间的关系,性能问题等等。

安全问题
作者、内嵌的图片、以及其他包含 URI 的元素作为参数可能间接引用用户输入。这种情况就需要注意[RFC1738],第六部分所描述的安全问题了。最常使用的用于提交表单请求的方法(HTTP和SMTP)是提供一些机密条款。通过表单请求机密信息的信息提供者,尤其是使用 type=passwordinput 元素的,应当让用户意识到保密性的缺失。

表单安全性
一个用户代理不应该发送任何用户没有明确要求被送出的文件。因此,HTML用户代理应当确认可能在 input 元素中的 value 中被建议的任何默认文件名。隐藏空间中不能指定文件。
这部分不包含数据加密机制,这个应当在其他的安全传输数据机制中。
一旦有文件被上传了,处理代理就应该进行处理,并保存适当地保存它。

使用内容类型 application/x-www-form-urlencoded 来发送大量二进制数据以及包含非ASCII字符的文本的效率是非常低的。multipart/form-data 这种内容类型就很适合用于提交包含文件、非ASCII数据和二进制数据的表单。

multipart/form-data 遵循所有的在[RFC2045]中所概述的多元 MIME 数据类型流。multipart/form-data 的定义在[IANA]记录上是可用的。

一个 multipart/form-data 消息包含很多的部分,每一个部分都代表了一个成功的控件(成功的控件表示在form元素中定义,并且有name的),这些部分以文档中出现的顺序相同的顺序被送到处理代理。部分的边界都不应该出现在任何数据中。这些是如何运作的超过了本文的描述范围。

因为需要支持所有的多元的 MIME 类型,所以每个部分都有一个可选的头部参数Content-Type被定义为text/plain。用户代理可以提供这个 Content-Type 头,伴随一个 charset 参数。

每一个部分预计包含:

  1. 一个 Content-Disposition 头,它的值是 form-data

  2. 一个 name 属性,用来指定和控件相同的名称的控件名。控件名本该将非 ASCII 字符集使用[RFC2045]中描述的方法进行编码。

NOTES 译者注
在火狐以及Chrome中测试的现象,当 name 被指定为中文名称的时候,form-data 里面的 name 也为中文,没有被转码。

因此,举个栗子吧,如果有一个空间的名称名字叫做 "mycontrol",则对应的部分应该被指定为:

Content-Disposition: form-data; name="mycontrol"

对于所有的MIME传递,"CR LF" (也就是 %0D%0A)用于数据中每行的分割。

每个部分都要被编码,而且如果这部分的值不遵循默认编码(7BIT),则 Content-Transfer-Encoding 头部需要被提供。参考[RFC2045] 的第六部分。

如果一个文件的内容也随着一个表单被提交,那么文件输入应该能够以适当的内容类型被识别,比如 application/octet-stream。如果多个文件被一个表单记录返回,那就应该作为 multupart/mixed被返回。

用户代理应当试图为每一个提交的文件提供文件名。文件名可以用 Content-Disposition: form-data 头部中的 filename 属性来定义。或者,因为是多个文件,可以用一个子部分 Content-Disposition: file 头部中指定。如果客户端的操作系统不是 US-ASCII 编码的,文件名应当对应或者使用[RFC2045]的方法进行编码。这对于有一些上传文件之间存在互相引用的文件的处理比较便利。比如一个 TeX 文件和它的 .sty 辅助样式描述。

下面一个例子是描绘了一个multipart/form-data编码示例。假设我们有这样的一个表单:

 <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,然后选择一个文本文件 file1.txt。用户代理应该传送这些数据:

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

如果用户选择了第二个文件 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--

赤石俊哉
127 声望227 粉丝