深入理解POST的本质

简介:

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

 
  1. <script type="text/javascript"
  2.         var objHTTP, strResult; 
  3.         objHTTP = new XMLHttpRequest(); 
  4.         objHTTP.open('POST'"Handler1.ashx"false); 
  5.         objHTTP.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); 
  6. objHTTP.send("data1=Hello&data2=Wrold"); 
  7.         strResult = objHTTP.responseText; 
  8.         alert(strResult); 
  9. </script> 

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

 
  1. public void ProcessRequest(HttpContext context) 
  2.        { 
  3.            context.Response.ContentType = "text/plain"
  4.            string s = context.Request["data1"] +" "+ context.Request["data2"]; 
  5.            context.Response.Write(s); 
  6.        } 
  7.    </script> 

得到结果如下:

FA99781338524B308436CA61EAD537E5

通过chrome也可以看到:

C86%60PG3DZ2REGCTVNKX7U(Q

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

再看一下Jquery的ajax方法。

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

 
  1. var option = { 
  2.             url: 'Handler1.ashx'
  3.            type: 'POST'
  4.             dataType: 'html'
  5.             success: function (result) { 
  6.                 alert(result); 
  7.             }, 
  8.             //data: { data1: "Hello", data2: "World" }两种写法皆可以 
  9.             data: "data1=Hello&data2=World" 
  10.         }; 
  11.         $.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部分:    

 
  1. var data = { "data""testdata" }; 
  2.      var option = { 
  3.          url: 'Handler1.ashx'
  4.          type: 'POST'
  5.          data: JSON.stringify(data),//取得json的string 
  6.          dataType: 'html'
  7.          contentType: 'application/json'
  8.          success: function (result) { alert(result); } 
  9.      }; 
  10.      $.ajax(option); 

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

 
  1. public void ProcessRequest(HttpContext context) 
  2.        { 
  3.            context.Response.ContentType = "text/plain"
  4.            StreamReader sr = new StreamReader(context.Request.InputStream, Encoding.UTF8); 
  5.            string s=sr.ReadToEnd(); 
  6.            context.Response.Write(s); 
  7.        } 

这里的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










本文转自cnn23711151CTO博客,原文链接: http://blog.51cto.com/cnn237111/1113546,如需转载请自行联系原作者



相关文章
|
22天前
|
网络协议 数据安全/隐私保护
get和post的区别
get和post的区别
19 0
|
3月前
|
网络协议 API C#
C# 中模拟 POST 和 GET 请求的原理与实践
【1月更文挑战第4天】在现代网络应用中,HTTP请求是客户端与服务器交互的基础。其中,GET和POST是最常用的两种请求方法。本文将介绍如何使用C#语言模拟这两种请求,并解释其背后的工作原理。我们将利用.NET框架中的HttpClient类来发送请求,并处理服务器的响应。通过本文,读者将能够理解HTTP请求的基本构成,学会在C#中编写代码来模拟这些请求,进而在开发过程中实现与Web服务的交互。
|
5天前
|
Web App开发 缓存 网络协议
get和post的区别!
get和post的区别!
|
8月前
|
缓存
get和post的区别
`GET` 和 `POST` 是 HTTP 请求方法,常用于客户端(如浏览器)与服务器之间的通信。
|
4月前
|
缓存 安全 数据安全/隐私保护
GET和POST有什么区别
GET和POST有什么区别
|
10月前
|
网络协议 安全 数据安全/隐私保护
GET与POST的区别
GET与POST的区别
97 0
|
10月前
|
Web App开发 网络协议 安全
GET和POST两种基本请求方法的区别
GET和POST两种基本请求方法的区别
|
网络协议 安全
GET 和 POST 的区别
GET 和 POST 的区别
104 0
|
缓存 安全 前端开发
GET和POST有什么区别?
GET和POST有什么区别?
GET和POST有什么区别?
|
Web App开发 网络协议 安全
GET 和 POST请求的本质区别是什么?
GET 和 POST请求的本质区别是什么?
89 0

热门文章

最新文章