首页 > HTTP之form表单

HTTP之form表单

2013-12-21   hisenKing

这次的项目遇到了两个问题,正好也是http的from的相关内容。做一下记录简单描述,两个问题分别是:1:form表单提交时的enctype问题;2:form中action的url链接带参数情况下,method的GET与POST区别。

第一个问题是C/S模式下,在对老代码进行重构的时候,为了测试新代码踩的坑,将原先程序运行客户端发送请求的包,在新的代码下重放时遇到。包如下:

POST /xxxx/xxxxxxx?version=1.10.12.242&req=ybdy&action=update HTTP/1.1

Host: http://xxxx
Connection: keep-alive
Content-Length: 926
Accept: application/json, text/javascript, */*
Content-Type: application/x-www-form-urlencoded
Origin: http://xxxx
User-Agent: Mozilla/5.0 (Windows NT 6.1) Chrome/21.0.1180.91 Safari/537.1
X-Requested-With: XMLHttpRequest
Referer: http://test.com.cn//xxxx/xxxxxxx?version=1.10.12.242&req=ybdy&id=587&num=16
Accept-Encoding: gzip,deflate
Accept-Language: en-us,en
Accept-Charset: iso-8859-1,*,utf-8
Cookie: USERID=hisen; version=1.10.12.242


xml=%253C%3Fxml%2520version%3D%25221.0%2522%2520encoding%3D%252...

初一看POST主体中有%符号,就直接复制了代码在本地进行urldecode想看看内容是什么。上面POST的主体部分,本身经过了urlencode,然后再提交的时候使用了Content-Type: application/x-www-form-urlencoded。这样就两次urlencode了。然后在服务端想当然的进行两次的urldecode,可想而知怎么样都得不到正确的结果。

第二个问题是与前端交互的时候,一个查询框交代了自己的需求,前端的同事在form表单中使用GET进行提交,导致后端php怎么样都得不到url中的参数

下面是针对上面两个问题的具体知识点:

Content-Type 实体中所承载对象的类型

enctype = content-type [CI] This attribute specifies the content type used to submit the form to the server (when the value of method is "post"). The default value for this attribute is "application/x-www-form-urlencoded". The value "multipart/form-data" should be used in combination with the INPUT element,type="file".


from表单支持的enctype有以下几种

1.application/x-www-form-urlencoded 在发送前编码所有字符(默认)

2.multipart/form-data 不对字符编码。在使用包含文件上传控件的表单时,必须使用该值。

3.text/plain 空格转换为 "+" 加号,但不对特殊字符编码。


默认的情况下当method使用POST会使用application/x-www-form-urlencoded,对提交的内容进行解码。然后web服务器会解析请求头,根据相关编码进行解码,在php获取参数的时候其实是已经web服务器处理过的数据。这也是为什么post在默认情况下可以有效的避免乱码问题的原因。

urlencode也叫百分号编码,常见的如空格符转义为%20,百分号转义为%25。

以下是《HTTP权威指南》中对URI字符集合的描述

未保留                   [A-Za-z0-9]|"-"|"_"|"."|"!"|"~"|"*"|"'"|"("|")"
保留                   ";"|"/"|"?"|":"|"@"|"&"|"="|""|"$"|","
转义                     "%" HEX HEX

GET与POST在from的action中的不同

If the method is "get" - -, 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" --, 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.

当使用get提交表单的话,浏览器是使用了action的值,然后追加‘?’发送数据,直接导致当action中存在?name=hisen这样的结构后面的参数全部丢失。使用post提交的时候是提取action的内容,并用enctype定义的属性创建信息,这样就不会丢失url中的参数了。

还有一个可能遇到的问题是,post提交的数据,当你想刷新的时候,浏览器会弹出提示,这样就影响用户体验。需要改成get提交就可以了

GET与POST的区别

  GET POST
BACK button/Reload Harmless Data will be re-submitted (the browser should alert the user that the data are about to be re-submitted)
Bookmarked Can be bookmarked Cannot be bookmarked
Cached Can be cached Not cached
Encoding type application/x-www-form-urlencoded application/x-www-form-urlencoded or multipart/form-data. Use multipart encoding for binary data
History Parameters remain in browser history Parameters are not saved in browser history
Restrictions on data length Yes, when sending data, the GET method adds the data to the URL; and the length of a URL is limited No restrictions
Restrictions on data type Only ASCII characters allowed No restrictions. Binary data is also allowed
Security GET is less secure compared to POST because data sent is part of the URL

Never use GET when sending passwords or other sensitive information!
POST is a little safer than GET because the parameters are not stored in browser history or in web server logs
Visibility Data is visible to everyone in the URL Data is not displayed in the URL

参考资料

http://zh.wikipedia.org/wiki/百分号编码

http://www.w3.org/TR/html401/interact/forms.html

《HTTP权威指南》

好久没更新了,需要除除草