http请求头中的content-type
web开发过程中客户端与服务端一般通过HTTP协议交互信息,而请求头和响应头用来承载这些交互信息。
请求头和响应头比较正式的叫法分别是请求报文和响应报文,统称为HTTP报文。下面是HTTP报文的结构:
HTTP报文分为报文首部和报文主体,两者之间用空行分隔(空行由回车符和换行符生成)。
content-type
在报文首部,用来表明报文主体的媒体类型(media type)。
在日常开发工作中,用的比较多的是GET和POST请求。
GET请求是把参数信息直接拼接在请求链接后边,没有报文主体,所以也就不需要设置content-type
。
而POST请求会把参数信息放在报文主体中,所以需要设置content-type
,告诉服务端主体信息的格式,以便服务端解码得到参数信息。
下面主要记录下POST请求常用的几个content-type
值:
- application/x-www-form-urlencoded
- multipart/form-data
- application/json
application/x-www-form-urlencoded
默认情况下,以post的方式提交表单数据时,content-type
自动设置为application/x-www-form-urlencoded
,数据被编码成以 '&' 分隔的键值对,同时以 '=' 分隔键和值。键和值中非字母或数字的字符会被URL编码。
下面是例子:
<form method="post" action="/test/index.php">
<div>
name:<input type="text" name="username" />
</div>
<div>
password:<input type="password" name="password" />
</div>
<button type="submit">Submit</button>
</form>
下面是请求报文的截图:
请求报文中content-type
被自动添加了,值是application/x-www-form-urlencoded
,请求参数处理成了'key=val&key=val'的形式。
如果不使用
form
元素,使用XMLHttpRequest
提交数据的话,要明确设置请求报文的content-type
,否则服务端可能无法获取到客户端传递的参数。
multipart/form-data
multipart/form-data
诞生的初衷是为了更方便的让用户上传文件。客户端会按照特殊的格式处理请求主体,服务端获取到请求主体后也会按照该格式的规则解析出数据。看一个例子:
<form method="post" action="/test/index.php" enctype="multipart/form-data">
<div>
name:<input type="text" name="username" />
</div>
<div>
password:<input type="password" name="password" />
</div>
<button type="submit">Submit</button>
</form>
给form
元素添加了enctype
属性,告诉服务端这次传递数据采用multipart/form-data
格式。
看一下请求报文:
请求主体被处理成了如下格式:
上传文件会再单独总结一篇笔记。
application/json
现在前后端通过AJAX交互,采用比较多的是application/json
。
下面看一个例子(根据经纬度获取实际地址):
请求主体是如下格式:
最后说一下
text/plain
,text/plain
表示将请求主体作为纯文本传输,数据没有固定格式,所以当数据提交到服务端时,服务端可能无法正确识别出参数。
POST提交表单数据时,设置content-type为
text/plain
,在php里,通过$_POST根本拿不到数据,数据被放在了$HTTP_RAW_POST_DATA里,具体参考这里和这里。