http请求头中的content-type属性
什么是Content-Type
Internet Media Type即互联网媒体类型,也叫做MIME类型,使用两部分标识符来确定一个类型。
在HTTP请求头中用Content-Type说明具体的媒体类型,即Content-Type是Internet Media Type在HTTP协议中的别称。
Content-Type的格式
type/subtype(;parameter)? type
Content-Type的格式为三个部分,分别是主类型(type)、子类型(subtype)和参数(parameter)。
主类型(type):主类型可以是任意的字符串,比如text。如果是*号则代表所有类型。
子类型(subtype):子类型可以是任意的字符串,比如html。如果是*号则代表所有类型。
参数(parameter):参数是可选的,可以在Content-Type中加入一些特殊的参数,比如Accept请求头的参数,常见的有用于设置字符编码的charset参数。
Content-Type: text/html;charset:utf-8;
Content-Type中常见的媒体格式类型
以text开头的媒体格式类型:
text/html: HTML格式。
text/plain:纯文本格式。
text/xml: XML格式。
以image开头的媒体格式类型:
image/gif:gif图片格式。
image/jpeg:jpg图片格式。
image/png:png图片格式。
以application开头的媒体格式类型:
application/xhtml+xml:XHTML格式。
application/xml: XML数据格式。
application/atom+xml:Atom XML聚合格式 。
application/json: JSON数据格式。
application/pdf:pdf格式 。
application/msword: Word文档格式。
application/octet-stream: 二进制流数据(如常见的文件下载)。
application/x-www-form-urlencoded: <form encType=””>中默认的encType,form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式)。
另外还有一种常见的媒体格式是上传文件之时使用的:
multipart/form-data : 需要在表单中进行文件上传时,就需要使用该格式。
以上就是开发中经常会用到的若干Content-Type的内容格式。
Spring MVC中关于Content-Type类型信息的使用
在Spring MVC中,主要就是使用@RequestMapping注解来处理请求,因此首先我们来看看@RequestMapping注解的Class定义。
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
String[] value() default {};
RequestMethod[] method() default {};
String[] params() default {};
String[] headers() default {};
String[] consumes() default {};
String[] produces() default {};
}
下面对注解提供的参数进行简单解析。
value:指定请求的实际地址, 比如/yanggb/info之类的请求路由。
method: 指定请求的method类型, 比如GET、POST、PUT、DELETE等。
consumes:指定处理请求的提交内容类型(Content-Type),例如application/json、text/html;等。
produces:指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回。
params:指定request中必须包含某些参数值,才让该方法处理。
headers:指定request中必须包含某些指定的header值,才能让该方法处理请求。
其中,consumes、produces可以使用Content-type中的信息对不需要的信息进行过滤,仅接受需要的数据;headers则可以使用Content-Type中的信息对请求进行过滤和判断。
Request Headers和Response Headers中的候选属性
Request Headers的候选属性
候选属性 | 说明 | 示例 |
Accept |
指定客户端能够接收的内容类型 |
Accept: text/plain, text/html |
Accept-Charset |
浏览器可以接受的字符编码集 |
Accept-Charset: iso-8859-5 |
Accept-Encoding |
指定浏览器可以支持的web服务器返回内容压缩编码类型 |
Accept-Encoding: compress, gzip |
Accept-Language |
浏览器可接受的语言 |
Accept-Language: en,zh |
Accept-Ranges |
可以请求网页实体的一个或者多个子范围字段 |
Accept-Ranges: bytes |
Authorization |
HTTP授权的授权证书 |
Authorization: Basic QWxhZLRpbjpvcGVuIHNoc2FtZQ== |
Cache-Control |
指定请求和响应遵循的缓存机制 |
Cache-Control: no-cache |
Connection |
表示是否需要持久连接。(HTTP 1.1默认进行持久连接) |
Connection: close |
Cookie |
HTTP请求发送时,会把保存在该请求域名下的所有cookie值一起发送给web服务器 |
Cookie: $Version=1; Skin=new; |
Content-Length |
请求的内容长度 |
Content-Length: 348 |
Content-Type |
请求的与实体对应的MIME信息 |
Content-Type: application/x-www-form-urlencoded |
Date |
请求发送的日期和时间 |
Date: Tue, 15 Nov 2018 08:22:31 GMT |
Expect |
请求的特定的服务器行为 |
Expect: 100-continue |
From |
发出请求的用户的Email |
From: user@email.com |
Host |
指定请求的服务器的域名和端口号 |
Host: www.yanggb.com |
If-Match |
只有请求内容与实体相匹配才有效 |
If-Match: "737060ff8c284d8af7ad2082f209582d" |
If-Modified-Since |
如果请求的部分在指定时间之后被修改则请求成功,未被修改则返回304代码 |
If-Modified-Since: Sat, 29 Oct 2018 19:43:31 GMT |
If-None-Match |
如果内容未改变返回304代码,参数为服务器先前发送的Etag,与服务器回应的Etag比较判断是否改变 |
If-None-Match: "737060cd8c284d8af7ad3082f209582d" |
If-Range |
如果实体未改变,服务器发送客户端丢失的部分,否则发送整个实体。参数也为Etag |
If-Range: "737060cd8c284d8af7ad3082f209582d" |
If-Unmodified-Since |
只在实体在指定时间之后未被修改才请求成功 |
If-Unmodified-Since: Sat, 29 Oct 2018 19:23:11 GMT |
Max-Forwards |
限制信息通过代理和网关传送的时间 |
Max-Forwards: 10 |
Pragma |
用来包含实现特定的指令 |
Pragma: no-cache |
Proxy-Authorization |
连接到代理的授权证书 |
Proxy-Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== |
Range |
只请求实体的一部分,指定范围 |
Range: bytes=500-999 |
Referer |
先前网页的地址,当前请求网页紧随其后,即来路 |
Referer: http://www.yanggb.com/yanggb1.html |
TE |
客户端愿意接受的传输编码,并通知服务器接受接受尾加头信息 |
TE: trailers,deflate;q=0.5 |
Upgrade |
向服务器指定某种传输协议以便服务器进行转换(如果支持) |
Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11 |
User-Agent |
User-Agent的内容包含发出请求的用户信息 |
User-Agent: Mozilla/5.0 (Linux; X11) |
Via |
通知中间网关或代理服务器地址,通信协议 |
Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1) |
Warning |
关于消息实体的警告信息 |
Warn: 199 Miscellaneous warning |
可以看到,Content-Type是Request Headers中的一个候选属性。
Response Headers的候选属性
候选属性 | 说明 | 示例 |
Accept-Ranges |
表明服务器是否支持指定范围请求及哪种类型的分段请求 |
Accept-Ranges: bytes |
Age |
从原始服务器到代理缓存形成的估算时间(以秒计,非负) |
Age: 12 |
Allow |
对某网络资源的有效的请求行为,不允许则返回405 |
Allow: GET, HEAD |
Cache-Control |
告诉所有的缓存机制是否可以缓存及哪种类型 |
Cache-Control: no-cache |
Content-Encoding |
web服务器支持的返回内容压缩编码类型 |
Content-Encoding: gzip |
Content-Language |
响应体的语言 |
Content-Language: en,zh |
Content-Length |
响应体的长度 |
Content-Length: 348 |
Content-Location |
请求资源可替代的备用的另一地址 |
Content-Location: /index.htm |
Content-MD5 |
返回资源的MD5校验值 |
Content-MD5: Q2hlY2sgSW50ZWdyaXR5IQ== |
Content-Range |
在整个返回体中本部分的字节位置 |
Content-Range: bytes 21010-47021/47022 |
Content-Type |
返回内容的MIME类型 |
Content-Type: text/html; charset=utf-8 |
Date |
原始服务器消息发出的时间 |
Date: Tue, 15 Nov 2018 08:22:22 GMT |
ETag |
请求变量的实体标签的当前值 |
ETag: "737060cd8c284d8af7ad3082f209582d" |
Expires |
响应过期的日期和时间 |
Expires: Thu, 01 Dec 2018 16:00:00 GMT |
Last-Modified |
请求资源的最后修改时间 |
Last-Modified: Tue, 15 Nov 2018 12:25:26 GMT |
Location |
用来重定向接收方到非请求URL的位置来完成请求或标识新的资源 |
Location: http://www.yanggb.com/yanggb2.html |
Pragma |
包括实现特定的指令,它可应用到响应链上的任何接收方 |
Pragma: no-cache |
Proxy-Authenticate |
它指出认证方案和可应用到代理的该URL上的参数 |
Proxy-Authenticate: Basic |
refresh |
应用于重定向或一个新的资源被创造,在5秒之后重定向(由网景提出,被大部分浏览器支持) |
Refresh: 5; url=
http://www.yanggb.com/yanggb9.html
|
Retry-After |
如果实体暂时不可取,通知客户端在指定时间之后再次尝试 |
Retry-After: 120 |
Server |
web服务器软件名称 |
Server: Apache/1.3.27 (Unix) (Red-Hat/Linux) |
Set-Cookie |
设置Http Cookie |
Set-Cookie: UserID=JohnDoe; Max-Age=3600; Version=1 |
Trailer |
指出头域在分块传输编码的尾部存在 |
Trailer: Max-Forwards |
Transfer-Encoding |
文件传输编码 |
Transfer-Encoding:chunked |
Vary |
告诉下游代理是使用缓存响应还是从原始服务器请求 |
Vary: * |
Via |
告知代理客户端响应是通过哪里发送的 |
Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1) |
Warning |
警告实体可能存在的问题 |
Warning: 199 Miscellaneous warning |
WWW-Authenticate |
表明客户端请求实体应该使用的授权方案 |
WWW-Authenticate: Basic |
具体使用示例
这里通过几个具体的实例来了解怎么在Spring MVC中使用两个Headers中的信息。
示例1:headers属性取Request Headers中的Referer属性。
@RequestMapping(value = "/yanggb2", method = RequestMethod.GET, headers="Referer=http://www.yanggb.com/yanggb1")
public void yanggb2() {
// 如果上一个页面的地址不是上面headers属性中Referer指定的地址,不会执行此方法
}
这里的headers里面可以匹配所有Headers里面可以出现的信息,不局限于Referer信息。
示例2:headers属性取Request Headers中的Accept属性。
@RequestMapping(value = "/yanggb2", headers = "Accept=application/json")
public void yanggb3(HttpServletResponse response) throws IOException {
// 表示响应的内容区数据的媒体类型为json格式,且编码为utf-8(客户端应该以utf-8解码)
response.setContentType("application/json;charset=utf-8");
// 写出响应体内容
String jsonData = "{\"username\":\"yanggb\",\"password\":\"123\"}";
response.getWriter().write(jsonData);
}
这样,服务器就会根据请求头【Accept=application/json】生产json数据。
当你有如下Accept头,将遵守如下规则进行应用:
①Accept:text/html,application/xml,application/json
将按照如下顺序进行produces的匹配 ①text/html ②application/xml ③application/json。
②Accept:application/xml;q=0.5,application/json;q=0.9,text/html。
将按照如下顺序进行produces的匹配 ①text/html ②application/json ③application/xml。
参数为媒体类型的质量因子,越大则优先权越高(从0到1)。
③Accept:*/*,text/*,text/html
将按照如下顺序进行produces的匹配 ①text/html ②text/* ③*/*。
即匹配规则为:最明确的优先匹配。
示例3:params属性取参数。
@RequestMapping(value = "/yanggb/{userId}", method = RequestMethod.GET, params = "yanggb1=yanggb2")
public void findUser(@PathVariable String userId) {
// 当请求中包含参数yanggb1时才会执行此方法
}
在上面的代码中,就起到了一个过滤的作用。
实例4:consumes/produces属性过滤请求。
@Controller
@RequestMapping(value = "/users", method = RequestMethod.POST, consumes="application/json", produces = "application/json")
@ResponseBody
public List<User> addUser(@RequestBody User userl) {
return List<User> users;
}
上面这个方法仅处理请求Content-Type为【application/json】类型的请求,produces标识处理请求中Accept头中包含了【application/json】的请求,同时暗示了返回的内容类型为【application/json】。
浏览器行为:Form表单提交
1、form表单常用属性
1
2
3
4
|
action:url 地址,服务器接收表单数据的地址
method:提交服务器的http方法,一般为post和get
name:最好好吃name属性的唯一性
enctype: 表单数据提交时使用的编码类型,默认使用 "pplication/x-www-form-urlencoded" ,如果是使用POST请求,则请求头中的content-type指定值就是该值。如果表单中有上传文件,编码类型需要使用 "multipart/form-data" ,类型,才能完成传递文件数据。
|
enctype为form表单数据的编码格式,Content-type为Http传输的数据的编码格式。分清两者
2、浏览器提交表单时,会执行如下步骤
1
2
3
4
|
1 、识别出表单中表单元素的有效项,作为提交项
2 、构建一个表单数据集
3 、根据form表单中的enctype属性的值作为content-type对数据进行编码
4 、根据form表单中的action属性和method属性向指定的地址发送数据
|
3、提交方式
1
2
|
1 、get:表单数据会被encodeURIComponent后以参数的形式:name1=value1&name2=value2 附带在url?后面,再发送给服务器,并在url中显示出来。
2 、post:enctype 默认 "application/x-www-form-urlencoded" 对表单数据进行编码,数据以键值对在http请求体重发送给服务器;如果enctype 属性为 "multipart/form-data" ,则以消息的形式发送给服务器。
|
Http协议行为:Http1.1协议
我们知道,HTTP 协议是以 ASCII 码传输,建立在 TCP/IP 协议之上的应用层规范。规范把 HTTP 请求分为三个部分:请求行、请求头、消息主体。类似于下面这样:
1
|
<method> <request-URL> <version> <headers> <entity-body>
|
协议规定 POST 提交的数据必须放在消息主体(entity-body)中,但协议并没有规定数据必须使用什么编码方式。实际上,开发者完全可以自己决定消息主体的格式,只要最后发送的 HTTP 请求满足上面的格式就可以。
但是,数据发送出去,还要服务端解析成功才有意义。一般服务端语言如 php、python 等,以及它们的 framework,都内置了自动解析常见数据格式的功能。服务端通常是根据请求头(headers)中的 Content-Type 字段来获知请求中的消息主体是用何种方式编码,再对主体进行解析。
所以说到 POST 提交数据方案,包含了 Content-Type 和消息主体编码方式两部分
Post请求下的Content-Type类型(编码类型)
1.application/x-www-form-urlencoded 键-值对
这应该是最常见的 POST 提交数据的方式了。浏览器的原生 <form> 表单,如果不设置 enctype
属性,那么最终就会以 application/x-www-form-urlencoded 方式提交数据。请求类似于下面这样(无关的请求头在本文中都省略掉了):
1
2
3
4
|
POST http:
Content-Type: application/x-www-form-urlencoded;charset=utf- 8
title=test&sub%5B%5D= 1 &sub%5B%5D= 2 &sub%5B%5D= 3
|
首先,Content-Type 被指定为 application/x-www-form-urlencoded;其次,提交的数据按照 key1=val1&key2=val2 的方式进行编码,key 和 val 都进行了 URL 转码。大部分服务端语言都对这种方式有很好的支持。例如 PHP 中,$_POST['title'] 可以获取到 title 的值,$_POST['sub'] 可以得到 sub 数组。
很多时候,我们用 Ajax 提交数据时,也是使用这种方式。例如 JQuery 和 QWrap 的 Ajax,Content-Type 默认值都是「application/x-www-form-urlencoded;charset=utf-8」。
2.multipart/form-data
这又是一个常见的 POST 数据提交的方式。我们使用表单上传文件时,必须让 <form> 表单的 enctype
等于 multipart/form-data。
直接来看一个请求示例:
form表单:
1
2
3
4
5
6
|
<form action= "/upload" enctype= "multipart/form-data" method= "post" >
Username: <input type= "text" name= "username" >
Password: <input type= "password" name= "password" >
File: <input type= "file" name= "file" >
<input type= "submit" >
</form>
|
Http协议请求:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
POST http:
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name= "text"
title
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name= "file" ; filename= "chrome.png"
Content-Type: image/png
PNG ... content of chrome.png ...
------WebKitFormBoundaryrGKCBY7qhFd3TrwA--
|
这个例子稍微复杂点。首先生成了一个 boundary 用于分割不同的字段,为了避免与正文内容重复,boundary 很长很复杂。然后 Content-Type 里指明了数据是以 multipart/form-data 来编码,本次请求的 boundary 是什么内容。消息主体里按照字段个数又分为多个结构类似的部分,每部分都是以 --boundary
开始,紧接着是内容描述信息,然后是回车,最后是字段具体内容(文本或二进制)。如果传输的是文件,还要包含文件名和文件类型信息。消息主体最后以 --boundary--
标示结束。关于 multipart/form-data 的详细定义,请前往 rfc1867 查看。
这种方式一般用来上传文件,各大服务端语言对它也有着良好的支持。
上面提到的这两种 POST 数据的方式,都是浏览器原生支持的,而且现阶段标准中原生 <form> 表单也只支持这两种方式(通过 <form> 元素的 enctype
属性指定,默认为 application/x-www-form-urlencoded
。其实 enctype
还支持 text/plain
,不过用得非常少)。
随着越来越多的 Web 站点,尤其是 WebApp,全部使用 Ajax 进行数据交互之后,我们完全可以定义新的数据提交方式,给开发带来更多便利。
3.application/json
application/json 这个 Content-Type 作为响应头大家肯定不陌生。实际上,现在越来越多的人把它作为请求头,用来告诉服务端消息主体是序列化后的 JSON 字符串。由于 JSON 规范的流行,除了低版本 IE 之外的各大浏览器都原生支持 JSON.stringify,服务端语言也都有处理 JSON 的函数,使用 JSON 不会遇上什么麻烦。
JSON 格式支持比键值对复杂得多的结构化数据,这一点也很有用。记得我几年前做一个项目时,需要提交的数据层次非常深,我就是把数据 JSON 序列化之后来提交的。不过当时我是把 JSON 字符串作为 val,仍然放在键值对里,以 x-www-form-urlencoded 方式提交。
Google 的 AngularJS 中的 Ajax 功能,默认就是提交 JSON 字符串。例如下面这段代码:
1
2
3
4
|
var data = { 'title' : 'test' , 'sub' : [ 1 , 2 , 3 ]};
$http.post(url, data).success(function(result) {
...
});
|
最终发送的请求是:
1
2
3
4
|
POST http:
Content-Type: application/json;charset=utf- 8
{ "title" : "test" , "sub" :[ 1 , 2 , 3 ]}
|
这种方案,可以方便的提交复杂的结构化数据,特别适合 RESTful 的接口。各大抓包工具如 Chrome 自带的开发者工具、Firebug、Fiddler,都会以树形结构展示 JSON 数据,非常友好。但也有些服务端语言还没有支持这种方式,例如 php 就无法通过 $_POST 对象从上面的请求中获得内容。这时候,需要自己动手处理下:在请求头中 Content-Type 为 application/json 时,从 php:
里获得原始输入流,再 json_decode
成对象。一些 php 框架已经开始这么做了。
当然 AngularJS 也可以配置为使用 x-www-form-urlencoded 方式提交数据。如有需要,可以参考这篇文章。
4.text/xml
它是一种使用 HTTP 作为传输协议,XML 作为编码方式的远程调用规范。典型的 XML-RPC 请求是这样的:
1
2
3
4
5
6
7
8
9
10
11
12
|
POST http:
Content-Type: text/xml
<?xml version= "1.0" ?>
<methodCall>
<methodName>examples.getStateName</methodName>
<params>
<param>
<value><i4> 41 </i4></value>
</param>
</params>
</methodCall>
|
XML-RPC 协议简单、功能够用,各种语言的实现都有。它的使用也很广泛,如 WordPress 的 XML-RPC Api,搜索引擎的 ping 服务等等。JavaScript 中,也有现成的库支持以这种方式进行数据交互,能很好的支持已有的 XML-RPC 服务。不过,我个人觉得 XML 结构还是过于臃肿,一般场景用 JSON 会更灵活方便。
相比之下,get方式的数据提交方式(编码方式)只有一种,就是application/x-www-form-urlencoding
MIME
"Multipurpose Internet Mail Extensions"多功能Internet邮件扩充服务,它是一种多用途网际邮件扩充协议。
1.作用
服务器会将它们发送的多媒体数据的类型告诉浏览器,而通知手段就是说明该多媒体的MIME类型,从而让浏览器知道接受到的信息哪些是MP3,哪些是Shockwave文件等等。
服务器将MIME标识符放入传送的数据中来告诉浏览器使用哪个插件读取相关文件
2.通用格式
type/subtype
3.细分
类型 | 描述 | 典型示例 |
text |
表明文件是普通文本,理论上是可读的语言 |
text/plain , text/html , text/css, text/javascript |
image |
表明是某种图像。不包括视频,但是动态图(比如动态gif)也使用image类型 |
image/gif , image/png , image/jpeg , image/bmp , image/webp |
audio |
表明是某种音频文件 |
audio/midi , audio/mpeg, audio/webm, audio/ogg, audio/wav |
video |
表明是某种视频文件 |
video/webm , video/ogg |
application |
表明是某种二进制数据 |
application/octet-stream , application/pkcs12 , application/vnd.mspowerpoint , application/xhtml+xml , application/xml , application/pdf,
application/json
|
对于text文件类型若没有特定的subtype,就使用 text/plain
。类似的,二进制文件没有特定或已知的 subtype,即使用 application/octet-stream
。
application/x-www-form-urlencoded与application/json
java_xxxx 2018-07-30 14:37:16 147712 收藏 142
文章标签: ajax请求 post anxious
版权
今天写项目的时候,前台发送数据到后端。前台的数据是发送了,但是后端收不到数据,后端我用@RequestBody,一直为null,然后去掉该注解,还是为null,再后来索性,只用一个IntegerNumber去接收,然而还是null…。最后请教了公司的程大神,才将bug解决掉了。
错误代码如下
js
getUserList:function(){
$.ajax({
type:"post",
url:this.api.userListUrl,
dateType:"json",
contentType : 'application/json',
data:this.queryParam,
success:function(result){
app.userList=result.data.rows;
app.pagination.total=result.data.total;
},
error:function(result){
}
});
}
controller代码:注意,一下代码其实没什么问题,但是接受参数的时候,自定义类前面的用@RequestBody才能接受,但问题就是,springmvc中,如果用了@RequestBody,就不能再接受单个的参数了,如 Integer i。
@RequestMapping("/user/page.do")
@ResponseBody
public ApiResult userPage(
@RequestBody MyPage page,
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date startTime,
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date endTime
){
System.out.println(page.getPageNumber());
System.out.println(page.getPageSize());
System.out.println(startTime);
System.out.println(endTime);
ApiResult apiResult = new ApiResult();
apiResult.setData(userService.userPage(page));
return apiResult;
}
改进,将ajax发送请求的application/json改为application/x-www-form-urlencoded,然后controller里的MyPage,就不用添加@RequesyBody了,于是既可以接受自定义的对象参数,又可以接受单个的参数。完美解决问题
application/x-www-form-urlencoded
1
下面我们来看看application/x-www-form-urlencoded与application/json的区别
说明:这两个都是发送请求的格式说明
1.application/x-www-form-urlencoded
在Form元素的语法中,EncType表明提交数据的格式 用 Enctype 属性指定将数据回发到服务器时浏览器使用的编码类型。 下边是说明: application/x-www-form-urlencoded: 窗体数据被编码为名称/值对。这是标准的编码格式。 multipart/form-data: 窗体数据被编码为一条消息,页上的每个控件对应消息中的一个部分。 text/plain: 窗体数据以纯文本形式进行编码,其中不含任何控件或格式字符。
补充
form的enctype属性为编码方式,常用有两种:application/x-www-form-urlencoded和multipart/form-data,默认为application/x-www-form-urlencoded。 当action为get时候,浏览器用x-www-form-urlencoded的编码方式把form数据转换成一个字串(name1=value1&name2=value2…),然后把这个字串append到url后面,用?分割,加载这个新的url。 当action为post时候,浏览器把form数据封装到http body中,然后发送到server。 如果没有type=file的控件,用默认的application/x-www-form-urlencoded就可以了。 但是如果有type=file的话,就要用到multipart/form-data了。浏览器会把整个表单以控件为单位分割,并为每个部分加上Content-Disposition(form-data或者file),Content-Type(默认为text/plain),name(控件name)等信息,并加上分割符(boundary).
application/json
有的时候发现 ajax请求中 content-type:application/json,这样也能在后台接受前台提交的数据,其实这个时候前端提交的数据是 json格式的字符串,后端要用@requestbody注解来接收
推荐链接:https://www.cnblogs.com/qlhMeiMei/p/6846392.html
content-type:application/json的数据格式:json字符串
application/x-www-form-urlencoded的数据格式:键值对:key-value
发现服务器的接口接收的数据的格式是form表单形式,而Angular的$http服务发送的post请求默认是json数据格式所以数据接收不到
推荐连接:https://blog.csdn.net/leftfist/article/details/79053389
https://blog.csdn.net/wopelo/article/details/78783442
/
ps:经过本人的试验总结,终于发现了一些东西,就是,当前台传递的参数,在后台不能由一个类全部接受的时候,就用application/x-www-form-urlencoded。
例如,我们在初次打开页面,且页面需要分页的功能的时候,后台接受代码如下。此时就有很多的参数,并且,如果此时用application/json的话,接受page就必须时候RequestBody,于是问题又来了,springmvc中共,如果使用了RequestBody,那么就不能有其他的不能有类接受的单个参数,于是下面的代码中的时间接受就为null。显然这用情况更适合使用application/x-www-form-urlencoded:发送的数据格式为键值对。而application/json为json字符串。
public ApiResult receive(Page page, ReportReceive filter,
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date startTime,
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date endTime) {
return new ApiResult(receiveService.page(page, filter, startTime, endTime));
}
如果前端发送给后台的数据只是一个对象(使用场景:如注册,保存空户,修改信息),那么我们就大课放心的使用application/json来处理数据,即:只需要在后台接受的时候添加@RequestBody即可
@RequestMapping("/reply/save.do")
@ResponseBody
public ApiResult replySave(@RequestBody ReportReceive receive) {
receive.setReplyTime(new Date());
if (receive.getReplyStatus() == 1) {
reportService.updateReplyCount(receive.getReportId());
}
return new ApiResult(receiveService.updateSelective(receive));
}
注:axios默认使用的是application/json格式,所以大家在向后台发送数据的时候,要小心喽。所以呢如果大家直接用$.ajax来提交post请求的话,最好好设置响应头contentType的值。
$.ajax({
type:"post",
url:this.api.treeListUrl,
dateType:"json",
contentType : 'application/json',
success:function(result){
app.options=result.data;
console.log(app.treeList);
},
error:function(result){
}
});
————————————————
版权声明:本文为CSDN博主「java_xxxx」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/java_xxxx/article/details/81205315