深入理解POST的本质

版权声明: 本文由 一只博客 发表于 bloghome博客

创新互联建站服务项目包括南湖网站建设、南湖网站制作、南湖网页制作以及南湖网络营销策划等。多年来,我们专注于互联网行业,利用自身积累的技术优势、行业经验、深度合作伙伴关系等,向广大中小型企业、政府机构等提供互联网行业的解决方案,南湖网站推广取得了明显的社会效益与经济效益。目前,我们服务的客户以成都为中心已经辐射到南湖省份的部分城市,未来相信会继续扩大服务区域并继续获得客户的支持与信任!

文章链接: https://www.bloghome.com.cn/user/cnn237111

HTTP中,提交数据的方式,最常用的就是GET和POST。

GET方式,搞WEB开发的都很熟悉,其实就是把参数编程键值对通过QueryString的方式放在URL尾部,比如: 

http://xxxx.com/test.aspx?a=1&b=2

POST方法,通常就是把要提交的表单放在一个FORM中,指明action后就可以提交数据。没有发现有诸如?a=1&b=2这样的键值对出现。

其实大家都被屏蔽了。事实上,打开W3C官网,可以看到如下

When the user submits a form (e.g., by activating a submit button), the user agent processes it as follows.

Step one: Identify the successful controls

Step two: Build a form data set

A form data set is a sequence of control-name/current-value pairs constructed from successful controls

Step three: Encode the form data set

The form data set is then encoded according to the content type specified by the enctype attribute of the FORM element.

Step four: Submit the encoded form data set

清楚的写到,第三步,对数据编码。根据 content type的内容指定的进行编码。

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.

如果方法是get的,就用问号,编码方式按照"application/x-www-form-urlencoded" 进行。user agent实际上指的就是浏览器,它会处理这一切,并指向一个编码后生成的Link。

如果是post方式,则会看使用哪种content type来编码。通过属性enctype指定编码content type的。

POST支持的content type方式有2种,默认的content type是application/x-www-form-urlencoded 。这种编码方式,其实也就是把表单名字和值组成键值对的形式,用‘&’符号连接该转码的转码拼接成个get方式差不多的那种格式。如原文写道:

application/x-www-form-urlencoded 

This is the default content type. Forms submitted with this content type must be encoded as follows:

Control names and values are escaped. Space characters are replaced by `+', and then reserved characters are escaped as described in [RFC1738], section 2.2: Non-alphanumeric characters are replaced by `%HH', a percent sign and two hexadecimal digits representing the ASCII code of the character. Line breaks are represented as "CR LF" pairs (i.e., `%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 `&'.

当然HTML4.0后还有multipart/form-data格式的,用来POST文件等二进制数据的。有兴趣的可以自己研究一下。

POST方式其实也是转成这种键值对的形式来post的,那么我们可以自己编写键值对,来post数据了吧?当然可以。其实Jquery中就是这么用的。先看个例子。直接使用原生的XMLHttpRequest来作POST操作。 

         var objHTTP, strResult;         objHTTP = new XMLHttpRequest();         objHTTP.open('POST', "Handler1.ashx", false);         objHTTP.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); objHTTP.send("data1=Hello&data2=Wrold");         strResult = objHTTP.responseText;         alert(strResult); 

 服务器端写(asp.net ashx文件) 

public void Proce***equest(HttpContext context)        {            context.Response.ContentType = "text/plain";            string s = context.Request["data1"] +" "+ context.Request["data2"];            context.Response.Write(s);        }    

得到结果如下:

深入理解POST的本质

通过chrome也可以看到:

深入理解POST的本质

和通过提交表单的方式是一样的效果。

再看一下Jquery的ajax方法。

其中data可以直接被赋值为key1=value1&key2=value2,如果有人喜欢json格式的赋值方式,那么ajax方法参数中有一个属性processData,默认是true,它会把json格式的数据转换成key1=value1&key2=value2的格式。真是省心省力。如下,两种赋值方式都可以写,个人偏爱json方式,简单明了。

var option = {             url: 'Handler1.ashx',            type: 'POST',             dataType: 'html',             success: function (result) {                 alert(result);             },             //data: { data1: "Hello", data2: "World" }两种写法皆可以             data: "data1=Hello&data2=World"         };         $.ajax(option);

注意,这种方式,默认的'Content-Type'都是'application/x-www-form-urlencoded'。如果更换Content-Type,就需要把processData设成false,同时,data的内容要自己自己控制好。

要用ajax方式Post文件就比较困难,因为Content-Type为multipart/form-data,而data无法手动赋值,因此比较困难。用firebug,查看post的一个doc文件,发现post的data全是乱码。

深入理解POST的本质

深入理解POST的本质

因此ajax方式上传文件一般都是包含一个或者使用flash的方式上传文件。

如果指明Content-Type是'application/json',那么data需要的是JSON的string,使用方法JSON.stringify(jsondata)可以获得这种string。但是要注意一点,不使用默认的application/x-www-form-urlencoded,数据是不会在Form Data中的,也就是用传统Request["data"]方法是获得不到数据的。对于特殊格式的数据就要特殊办法处理。那处理的方式就是强行读取Request.InputStream。当然对于默认的application/x-www-form-urlencoded也是可以采用这种最原始但是最有效的。

比如下面的例子:js部分:    

var data = { "data": "testdata" };      var option = {          url: 'Handler1.ashx',          type: 'POST',          data: JSON.stringify(data),//取得json的string          dataType: 'html',          contentType: 'application/json',          success: function (result) { alert(result); }      };      $.ajax(option);

传送的是application/json类型。那么后台就得如下写法:      

public void Proce***equest(HttpContext context)        {            context.Response.ContentType = "text/plain";            StreamReader sr = new StreamReader(context.Request.InputStream, Encoding.UTF8);            string s=sr.ReadToEnd();            context.Response.Write(s);        }

这里的s就是纯的json字符串,要转变成json对象可以使用JSON.NET或者FastJson等第三方类库来实现。

================

参考资料

http://en.wikipedia.org/wiki/POST_(HTTP)

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

http://en.wikipedia.org/wiki/XMLHttpRequest


当前文章:深入理解POST的本质
文章路径:http://pwwzsj.com/article/jgejij.html