关于HTTP请求(主要是POST和GET)
前言
最近在做java后台(ssm+maven), 设计到http中几种请求方法, 即在springMVC中使用restful风格的url, 会涉及到POST, GET, DELETE, PUT这几种请求http的请求方法. 故在一番复习之后,向大家简单的分享这个几种http请求方式. 本文主要介绍POST和GET请求方式.
附上HTTP请求和响应的报文结构图
请求报文
<request-line>
<request-header>
<blank-line>
[<request-body>]
响应报文
<response-status-line>
<response-header>
<blank-line>
[<response-body>]
一.前言(post和get最直观的区别)
- GET请求把参数直接包含在请求的URL中
- POST请求是通过request body 即请求正文传递参数
- GET请求在url中传送的参数长度是有限制的
- GET比POST不安全, 所以不能传递敏感信息等等.
二.生动的比喻
我在网上看到一段关于http请求方式的比喻.我觉得很形象生动, 故在此 引用一下
学过操作系统的童鞋都知道http是基于tcp/ip的一种互联网通讯协议.
所以说http的底层是tcp/ip. 而GET和POST是http请求的两种方式. 故get和post的底层也是基于tcp的.
其实get和post做的事情都是一样的,
就像你要给get请求加上request body,
给post请求加上url请求参数在技术上也是完全可行的.
比喻
在互联网的世界中, tcp就像是汽车, 我们用tcp进行运输数据, 类比现实生活中汽车也分好多种-货车,客车, 加急车等等, 当然有了这些车之后, 不可避免的就有交通法规, 而交通法规就类比互联网中的http协议, 该http协议(交通规则)设定了几个服务类别, 有get, post, put, delete等, 而执行每一种服务,如执行get请求的时候-给汽车贴上get的标签(设置method为get). 则规定该汽车要把传送的数据放在车顶上(url)以方便记录. 而如果是post服务的话, 就在汽车上贴上post标签, 也就是把货物放在车厢里. 当然,你可以在get的时候往车厢里偷偷放点数据, 至于接不解析(接不接受)就是要服务器的事情了. 你也可以在post的时候, 在车顶放一些数据, 虽然这样很没有意义, 但是表明http只是一个行为准则. 而tcp才是get和post实现的根本.
值得注意
-
get请求只会产生一个TCP数据包.
当使用get方式提交请求的时候, 浏览器会把请求的header和数据一起发送出去, 服务器端响应200返回数据
-
post请求会产生两个TCP数据包.
对于使用post方式提交, 浏览器会先发送header, 服务器响应100 continue, 浏览器再次发送data, 服务器响应200返回数据. 也就是说get只需要汽车跑一趟就把货物送到了. 但是post的话要跑两趟, 第一趟去和服务器打个招呼说:嗨,哥们,我等一下要送一批货来, 你打开门迎接我一下. 然后第二趟把数据送过来. 有人会说post比较消耗时间. 其实不然, 在网络好的请求下, 浏览器发一次包的时候和发两次包的时间基本可以无视, 还有并不是所有的浏览器在post请求的时候都会发送2次包. 如火狐就只发送一次.
三.请求报文详细解析
一. 请求行 - POST /index.html /HTTP/1.1
组成: 请求方法字段 空格 url字段 空格 http协议版本字段 回车换行
1. 如果是get请求的话, 还会在url后面即进行请求参数拼接
index.html?username=daejong&password=123456
2. 如果是post请求的话, 请求参数会放在request body请求体中, 见下.
二. 请求头 - 以key-value键值对,
主要通知服务器有关客户端请求的信息.
如:
User-Agent: 产生请求的浏览器类型
Accpet: 客户端可以识别的内容类型列表
Host: 请求的主机名
Content-Type: application/json 等等
三. 空行 - 回车 换行符
用来通知服务器以下 没有请求头了. 用于请求头和请求体的分割.
四. 请求体-数据
注意:
1. 请求体不在GET请求中使用, 而是在POST请求的方法中使用.
2. 通常在使用POST的请求的时候, 指定Content-Type, Content-Length.指定内容类型, 如通常我们统一请求和响应的数据格式为json.
就要指定Content-Type为application/json
四.响应报文详细解析
一. 响应行-状态行
提到状态行-不得不说一下状态码.
状态码由三位数字组成.
1. 1xx 表示请求已经接收, 继续处理
2. 2xx 表示成功接收,理解,接收
3. 3xx 表示重定向, 要完成请求必须更进一步的操作.
4. 4xx 表示客户端错误-请求有语法错误或者无法实现.
5. 5xx 表示拂去其出错了-如服务器未能实现合法的请求.
常见的状态码:
1. 200 ok, 客户端请求成功
2. 400 bad request, 客户端请求有语法错误, 服务器无法解析
3. 403 forbidden, 服务器接收到请求, 到时拒绝提供服务
4. 404 not found, 请求资源不存在
5. 500 internal server error, 服务器发送不可预期的错误.
6. 503 server unavailable 服务器当前不能处理客户端请求, 一段时间后可能恢复正常.
响应头 和 响应体类似请求报文的请求头和请求体.
五. 总结
get请求, 请求的数据会附在url之后, 也就是放在request-line中, 用?进行分割
post请求, 把请求的数据放置在http包的包体request-body中,
也就是get请求的数据会在地址栏显示, 而post不会.
-
传输的数据的大小
首先声明: http协议并没有规定对传输的数据的大小进行限制, 也没有对url的长度进行限制,而实际开发中主要限制有: get: 特定浏览器和服务器对url长度有限制. 如IE一般限制请求url长度为2k个字节. post: 由于不是通过url传值, 值时放在请求体中, 所以理论上不受限制.
安全性: post的安全性要比get安全性高.