一、FormData和Payload是浏览器传输给接口的两种格式,这两种方式浏览器是通过Content-Type来进行区分的。
- application/x-www-form-urlencoded,则为formdata
- application/json或multipart/form-data,则为 request payload
二、Content-Type
Content-Type是指 http 请求发送信息至服务器时的内容编码类型。用于表明发送数据流的类型,服务器根据编码类型使用特定的解析方式,获取数据流中的数据。
常用的Content-Type有如下:
页面资源类型:text/html, text/plain, text/css, text/javascript,
image/jpeg, image/png, image/gif
ajax&表单提交&上传文件:application/x-www-form-urlencoded, multipart/form-data,
application/json, application/xml
三、FormData & Request Payload 的区别
注意:Request Payload更准确的说是http request的payload body
当POST请求的
请求头
里设置Content-Type: application/x-www-form-urlencoded(默认), 参数在
请求体
以标准的Form Data的形式提交,以&符号拼接,参数格式为key=value&key=value&key=value…
当POST请求的
请求头
里设置Content-Type:application/json,参数在
请求体
以JSON形式提交,参数格式为JSON格式{“key”:“value”,“key”:“value”…}。
HTTP请求报文由3部分组成(请求行+请求头+请求体)
两种提交都会将数据放在message-body的payload中,只是因为Content-Type设置的不同,并不是数据提交方式的不同,为什么有时候后端拿不到值呢?这就不得不说服务器对payload的解析方式了
四、服务器解析 POST 数据
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)是获取不到的。
五、php接收request payload的数据的方法
只能通过获取原始数据流的方式来进行解析请求数据
$data = file_get_contents( “php://input”);