用户完成表单输入通过修改控件内容,然后提交表单交给代理处理表单内容。
思考:即表单涉及的角色有:用户、代理。代理理解为浏览器,用户把表单内容交给浏览器代理,浏览器将表单内容进行进一步处理,提交给真正的应用程序(web 服务器)处理(通过http协议进行交互)
也就是表单是用户与服务器之间进行信息交流的媒介
表单,是html文档的一部分,包含 普通内容(normal content),标记(markup),特殊元素:控件 control,和控件 control上的标签(label)
思考:上述表明了表单是html文档的一个部分,由四个部分组成,表单的核心是control 控件,label表单控件的文本标签,通过 for属性值与控件 name属性关联。
用户通过命名控件(named control)与表单交互。
提交表单进行处理时,某些控件的名称(name)与当前值(value)配对,并且这些对与表单一起提交。 提交名称/值对的那些控件称为成功控件(successful control )。
思考:用户修改控件与表单交互,提交表单与浏览器代理交互,浏览器发送请求给web服务器,完成用户与web服务器的通信
控件可大致分为两类:内容控件和成功控件,前者完成用户信息收集功能,后者提交表单给代理服务器,完成与web服务器通信的功能
buttons,CheckBox,radio buttons,menu,text input,file select,hide control,Object controls
不同的内容控件对应着用户输入的内容,用户想要输入的信息一般有文本,密码,文件,单选框,复选框,选项列表,这些功能的实现主要由 input 标签(不同type)和其他一些标签实现
当用户提交表单时(例如,通过激活submit按钮),用户代理按如下方式处理它
校验 successful 控件
构建表单数据集合(form data set)
表单数据集是由成功控件(successful control)构造的一系列控件名称/当前值对(control-name/current-value pairs )
编码表单数据集合
根据form 表单的enctype属性指定的content-type进行编码
提交编码后的表单数据
编码后的数据通过表单的method 属性发送指定的协议发送到由action属性指定的代理
method content-type 表单内容 get 默认application/x-www-form-urlencoded URL post 由表单的 enctype指定 请求体中
- If the method is “get” and the action is an HTTP URI, the user agent takes the value of action, appends a `?’ to it, then appends the form data set, encoded using the “application/x-www-form-urlencoded” content type. The user agent then traverses the link to this URI. In this scenario, form data are restricted to ASCII codes.
- If the method is “post” and the action is an HTTP URI, the user agent conducts an HTTP “post” transaction using the value of the action attribute and a message created according to the content type specified by the enctype attribute.
默认的内容类型 content type
控件名和值被转义,空格–+,其他保留字符通过 [RFC1738], 标准转义。
编码规则
原文 转义 space 空格 +
非字母数字字符 %HH
代表字符的ASCII码换行符 CR LF
%0D%0A
编码顺序
控件名称/值以它们在文档中出现的顺序列出。 名称与值之间以’=‘分隔,名称/值对之间由’&'分隔。
The control names/values are listed in the order they appear in the document. The name is separated from the value by
=' and name/value pairs are separated from each other by
&’.
内容类型“ application / x-www-form-urlencoded”对于发送大量二进制数据或包含非ASCII字符的文本效率不高。 内容类型“ multipart / form-data”应用于提交包含文件,非ASCII数据和二进制数据的表单。
A “multipart/form-data” message contains a series of parts, each representing a successful control.
“多部分/表单数据”消息包含一系列部分,每个部分代表成功的控件。
每一个部分都可以指定他的内容类型(Content-Type),默认是"text/plain",用户代理应该提供“Content-Type”标头,并附带一个“charset”参数。
每部分内容一般包含些什么?
每个部分都将被编码,如果不使用用默认编码方式,需要设置一个Content-Transfer-Encoding
头设置编码方式。
如果上传的表单内容是文件,需要使用合适的内容类型进行表示(例如:application/octet-stream
)
如果要通过单个表单条目返回多个文件,则应以嵌入在 multipart / form-data
中以“multipart / mixed
的形式返回它们
用户代理应该尝试为每个提交的文件提供一个文件名。文件名可以用“content - dispose: form-data”标头的“filename”参数指定,对于多个文件,也可以在子部分的“content - dispose: file”标头中指定。如果客户端操作系统的文件名不是US-ASCII,则可以使用[RFC2045]的方法来近似或编码该文件名。这对于某些情况很方便,例如,上传的文件可能包含对彼此的引用
以下示例说明了“多部分/表单数据”编码。 假设我们具有以下形式
<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-