深刻理解POST的本质

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

文章连接: https://www.bloghome.com.cn/user/cnn237111html

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

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

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

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

其实你们都被屏蔽了。事实上,打开W3C官网,能够看到以下编程

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

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操做。 

<script type="text/javascript">         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); </script>

 服务器端写(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);        }    </script>

获得结果以下:

FA99781338524B308436CA61EAD537E5

经过chrome也能够看到:

C86%60PG3DZ2REGCTVNKX7U(Q

和经过提交表单的方式是同样的效果。

再看一下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全是乱码。

SMGD}9M)B6{8V~3%MSE%9]7

`WAIZCJA5VEF}L{(7%M]4C1

所以ajax方式上传文件通常都是包含一个<frame>或者使用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

相关文章
相关标签/搜索