[转]HTTP请求中的form data和request payload的区别
本文转自:http://www.cnblogs.com/btgyoyo/p/6141480.html
jQuery的ajax方法和post方法分别发送请求,在后台Servlet进行处理时结果是不一样的,比如用$.ajax方法发送请求时(data参数是一个JSON.stringify()处理后的字符串,而不是一个JSON对象),servlet里可以这样使用Gson来解析:
new Jsonparser().parse(request.getReader())
但此时是不可用request.getParam(key) 来取值的。
如果用$.post方法来发送请求(data参数是一个JSON对象,而不要再用JSON.stringify()处理为字符串了),结果恰恰相反。
在Chrome中调试发现,$.ajax发送的请求显示在request payload下面,而使用$.post方法发送的请求显示在form data下面。有什么区别呢?
关键就是设置Content-type这个Header为application/x-www-form-urlencoded,实际上对于常规的HTML页面上的form的Content-type默认就是这个值。
这里要注意post请求的Content-Type为application/x-www-form-urlencoded,参数是在请求体中,即上面请求中的Form Data。
在servlet中,可以通过request.getParameter(name)的形式来获取表单参数。
而如果使用原生AJAX POST请求的话:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
function getXMLHttpRequest() { var xhr; if (window.ActiveXObject) { xhr= new ActiveXObject( "Microsoft.XMLHTTP" ); } else if (window.XMLHttpRequest) { xhr= new XMLHttpRequest(); } else { xhr= null ; } return xhr; } function save() { var xhr = getXMLHttpRequest(); xhr.open( "post" , "http://127.0.0.1:8080/test/test.do" ); var data = "name=mikan&address=street..." ; xhr.send(data); xhr.onreadystatechange= function () { if (xhr.readyState == 4 && xhr.status == 200) { alert( "returned:" + xhr.responseText); } }; } |
通过chrome的开发者工具看到请求头如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
RequestURL:http: //127.0.0.1:8080/test/test.do Request Method:POST Status Code:200 OK Request Headers Accept:*/* Accept-Encoding:gzip,deflate,sdch Accept-Language:zh-CN,zh;q=0.8,en;q=0.6 AlexaToolbar-ALX_NS_PH:AlexaToolbar/alxg-3.2 Connection:keep-alive Content-Length:28 Content-Type:text/plain;charset=UTF-8 Cookie:JSESSIONID=C40C7823648E952E7C6F7D2E687A0A89 Host:127.0.0.1:8080 Origin:http: //127.0.0.1:8080 Referer:http: //127.0.0.1:8080/test/index.jsp User-Agent:Mozilla/5.0 (Windows NT 6.1)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.149 Safari/537.36 Request Payload name=mikan&address=street Response Headers Content-Length:2 Date:Sun, 11 May 2014 11:49:23 GMT Server:Apache-Coyote/1.1 |
注意请求的Content-Type为text/plain;charset=UTF-8,而请求表单参数在RequestPayload中。
那么servlet中通过request.getParameter(name)却是空。为什么呢?而这样的参数又该怎么样获取呢?
为了搞明白这个问题,查了些资料,也看了Tomcat7.0.53关于请求参数处理的源码,终于搞明白了是怎么回事。
HTTP POST表单请求提交时,使用的Content-Type是application/x-www-form-urlencoded,而使用原生AJAX的POST请求如果不指定请求头RequestHeader,默认使用的Content-Type是text/plain;charset=UTF-8。
由于Tomcat对于Content-Type multipart/form-data(文件上传)和application/x-www-form-urlencoded(POST请求)做了“特殊处理”。下面来看看相关的处理代码。
Tomcat的HttpServletRequest类的实现类为org.apache.catalina.connector.Request(实际上是org.apache.coyote.Request),而它对处理请求参数的方法为protected void parseParameters(),这个方法中对Content-Type multipart/form-data(文件上传)和application/x-www-form-urlencoded(POST请求)的处理代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
protectedvoid parseParameters() { //省略部分代码...... parameters.handleQueryParameters(); // 这里是处理url中的参数 //省略部分代码...... if ( "multipart/form-data" .equals(contentType)) { // 这里是处理文件上传请求 parseParts(); success = true ; return ; } if (!( "application/x-www-form-urlencoded" .equals(contentType))) { // 这里如果是非POST请求直接返回,不再进行处理 success = true ; return ; } //下面的代码才是处理POST请求参数 //省略部分代码...... try { if (readPostBody(formData, len)!= len) { // 读取请求体数据 return ; } } catch (IOException e) { // Client disconnect if (context.getLogger().isDebugEnabled()) { context.getLogger().debug( sm.getString( "coyoteRequest.parseParameters" ),e); } return ; } parameters.processParameters(formData, 0 , len); // 处理POST请求参数,把它放到requestparameter map中(即request.getParameterMap获取到的Map,request.getParameter(name)也是从这个Map中获取的) // 省略部分代码...... } protected int readPostBody( byte body[], int len) throws IOException { int offset = 0 ; do { int inputLen = getStream().read(body, offset, len - offset); if (inputLen <= 0 ) { return offset; } offset += inputLen; } while ((len - offset) > 0 ); return len; } |
从上面代码可以看出,Content-Type不是application/x-www-form-urlencoded的POST请求是不会读取请求体数据和进行相应的参数处理的,即不会解析表单数据来放到request parameter map中。所以通过request.getParameter(name)是获取不到的。
那么这样提交的参数我们该怎么获取呢?
当然是使用最原始的方式,读取输入流来获取了,如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
privateString getRequestPayload(HttpServletRequest req) { StringBuildersb = new StringBuilder(); try (BufferedReaderreader = req.getReader();) { char []buff = new char [ 1024 ]; intlen; while ((len = reader.read(buff)) != - 1 ) { sb.append(buff, 0 , len); } } catch (IOException e) { e.printStackTrace(); } returnsb.toString(); } |
当然,设置了application/x-www-form-urlencoded的POST请求也可以通过这种方式来获取。
所以,在使用原生AJAX POST请求时,需要明确设置Request Header,即:
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
[转]HTTP请求中的form data和request payload的区别的更多相关文章
- HTTP 请求中的 Form Data 与 Request Payload 的区别
HTTP 请求中的 Form Data 与 Request Payload 的区别 前端开发中经常会用到 AJAX 发送异步请求,对于 POST 类型的请求会附带请求数据.而常用的两种传参方式为:Fo ...
- HTTP请求中的form data和request payload的区别
HTML <form> 标签的 enctype 属性 在下面的例子中,表单数据会在未编码的情况下进行发送: <form action="form_action.asp&qu ...
- HTTP请求中的Form Data与Request Payload的区别
前端开发中经常会用到AJAX发送异步请求,对于POST类型的请求会附带请求数据.而常用的两种传参方式为:Form Data 和 Request Payload. GET请求 使用get请求时,参数会以 ...
- 【转】HTTP请求中的form data和request payload的区别
jQuery的ajax方法和post方法分别发送请求,在后台Servlet进行处理时结果是不一样的,比如用$.ajax方法发送请求时(data参数是一个JSON.stringify()处理后的字符串, ...
- axios 请求中的Form Data 与 Request Payload的区别
在vue项目中使用axios发post请求时候,后台返回500. 发现是form Data 和 Request payload的问题. 后台对两者的处理方式不同,导致我们接收不到数据. 解决方案:使用 ...
- [整理]Ajax Post请求下的Form Data和Request Payload
Ajax Post请求下的Form Data和Request Payload 通常情况下,我们通过Post提交表单,以键值对的形式存储在请求体中.此时的reqeuest headers会有Conten ...
- form data和request payload的区别
HTML <form> 标签的 enctype 属性 在下面的例子中,表单数据会在未编码的情况下进行发送: <form action="form_action.asp&qu ...
- 【转】form data和request payload的区别
HTML <form> 标签的 enctype 属性 在下面的例子中,表单数据会在未编码的情况下进行发送: <form action="form_action.asp&qu ...
- AJAX POST请求中参数以form data和request payload形式在servlet中的获取方式
转载:http://blog.csdn.net/mhmyqn/article/details/25561535 HTTP请求中,如果是get请求,那么表单参数以name=value&name1 ...
随机推荐
- WebRequest请求被中止: 未能创建 SSL/TLS 安全通道
使用System.Net.WebRequest.Create(url)抓取某网站信息时 ,出现“未能创建 SSL/TLS 安全通道”此条异常信息 解决方案 引用:using System.Net; 在 ...
- SSE sqrt还是比C math库的sqrtf快了不少
#include <stdio.h> #include <xmmintrin.h> #define NOMINMAX #include <windows.h> #i ...
- java之JIT(Just in time)
Java程序最初是通过解释器进行解释执行的,当虚拟机发现某个方法或代码块运行的特别频繁时,会把这些代码认定为“热点代码”(Hot Spot Code).为了提高热点代码的执行效率,在运行时,虚拟机会把 ...
- Memoization-329. Longest Increasing Path in a Matrix
Given an integer matrix, find the length of the longest increasing path. From each cell, you can eit ...
- linux下程序编译出错解决方法
一 *** No rule to make target 'subscribe_pkg/CMakeFiles/subscribe_pkg_node.dir/build'. 停止.CMakeFiles/ ...
- 关于使用Iscroll.js异步加载数据后不能滑动到最底端的问题解决方案
关于使用Iscroll.js异步加载数据后不能滑动到最底端,拉到最下边又弹回去的问题困扰了我老半天,相信很多朋友都遇到了.我刚好不小心解决了,和大家分享一下.由于各种忙,下边就直接上代码吧. (前提是 ...
- JAVA抽象类和抽象方法(abstract)
一.抽象(abstract)的使用 当父类的某些方法不确定时,可以用abstract关键字来修饰该方法[抽象方法],用abstract来修饰该类[抽象类]. 我们都知道,父类是将子类所共同拥有的属性和 ...
- java保留小数点两位的4种方法
import java.math.BigDecimal; import java.text.DecimalFormat; import java.text.NumberFormat; public c ...
- Swift 里字符串(七)stringIndex
在 String 里,用来索引 Character 的,不是整数,而是StringIndex 内部结构 extension String { /// A position of a character ...
- Alamofire源码导读二:发起请求及内部加锁的逻辑
以创建一个 DataRequest 为例子  发起请求 创建 SessionManager 顺带也创建了一个 SessionDelegate 持有一个urlSession,持有一个串行的 Dispa ...