HTTP 报文组成
http报文:由请求报文和响应报文组成
请求报文:由请求行、请求头、空行、请求体四部分组成
响应报文:由状态行、响应头、空行、响应体四部分组成
- 请求行:包含http方法,请求地址,http协议以及版本
- 请求头/响应头:就是一些key:value来告诉服务端我要哪些内容,要注意什么类型等,请求头/响应头每一个字段详解
- 空行:用来区分首部与实体,因为请求头都是key:value的格式,当解析遇到空行时,服务端就知道下一个不再是请求头部分,就该当作请求体来解析了
- 请求体:请求的参数
- 状态行:包含http协议及版本、数字状态码、状态码英文名称
- 响应体:服务端返回的数据
HTTP 请求方法(9种)
HTTP1.0: GET、POST、HEAD
HTTP1.1: PUT、PATCH、DELETE、OPTIONS、TRACE、CONNECT
| 方法 | 描述 |
|---|---|
| GET | 获取资源 |
| POST | 传输资源,通常会造成服务器资源的修改 |
| HEAD | 获得报文首部 |
| PUT | 更新资源 |
| PATCH | 对PUT的补充,对已知资源部分更新 菜鸟 |
| DELETE | 删除资源 |
| OPTIONS | 列出请求资源支持的请求方法,用来跨域请求 |
| TRACE | 追踪请求/响应路径,用于测试或诊断 |
| CONNECT | 将连接改为管道方式用于代理服务器(隧道代理下面有讲) |
GET 和 POST 的区别
GET在浏览器回退时是无害的,而POST会再次发起请求GET请求会被浏览器主动缓存,而POST不会,除非手动设置GET请求参数会被保留在浏览器历史记录里,而POST中的参数不会被保留GET请求在URL中传递的参数有长度限制(浏览器限制大小不同),而POST没有限制GET参数通过URL传递,POST放在Request body中GET没有POST安全,因为GET请求参数直接暴露在URL上,所以不能用来传递敏感信息GET请求只能进行URL编码,而POST支持多种编码方式- 对参数的数据类型,
GET只接受ASCII字符,而POST没有限制 GET产生一个TCP数据包,POST产生两个数据包(Firefox只发一次)。GET浏览器把 http header和data一起发出去,响应成功200,POST先发送header,响应100 continue,再发送data,响应成功200
什么是持久连接/长连接
http1.0协议采用的是"请求-应答"模式,每个请求/应答客户与服务器都要新建一个连接,完成之后立即断开连接(http协议为无连接的协议)
http1.1版本支持长连接,即请求头添加Connection: Keep-Alive,使用Keep-Alive模式(又称持久连接,连接复用)建立一个TCP连接后使客户端到服务端的连接持续有效,可以发送/接受多个http请求/响应,当出现对服务器的后续请求时,Keep-Alive功能避免了建立或者重新建立连接
长连接优缺点
优点
减少CPU及内存的使用,因为不需要经常建立和关闭连接支持管道化的请求及响应模式减少网络堵塞,因为减少了TCP请求减少了后续请求的响应时间,因为不需要等待建立TCP、握手、挥手、关闭TCP的过程- 发生错误时,也
可在不关闭连接的情况下进行错误提示
缺点
一个长连接建立后,如果一直保持连接,对服务器来说是多么的浪费资源呀,而且长连接时间的长短,直接影响到服务器的并发数
还有就是可能造成队头堵塞(下面有讲),造成信息延迟
如何避免长连接资源浪费?
- 客户端请求头声明:
Connection: close,本次通信后就关闭连接 - 服务端配置:如Nginx,设置
keepalive_timeout设置长连接超时时间,keepalive_requests设置长连接请求次数上限
什么是管线化(管道化)
http1.1在使用长连接的情况下,建立一个连接通道后,连接上消息的传递类似于
请求1 -> 响应1 -> 请求2 -> 响应2 -> 请求3 -> 响应3
管理化连接的消息就变成了类似这样
请求1 -> 请求2 -> 请求3 -> 响应1 -> 响应2 -> 响应3
管线化是在同一个TCP连接里发一个请求后不必等其回来就可以继续发请求出去,这可以减少整体的响应时间,但是服务器还是会按照请求的顺序响应请求,所以如果有许多请求,而前面的请求响应很慢,就产生一个著名的问题队头堵塞(下面有讲解决方法)
解决 HTTP 队头阻塞
http1.0协议采用的是请求-应答模式,报文必须是一发一收,就形成了一个先进先出的串行队列,没有轻重缓急的优先级,只有入队的先后顺序,排在最前面的请求最先处理,就导致如果队首的请求耗时过长,后面的请求就只能处于阻塞状态,这就是著名的队头阻塞问题。解决如下:
并发连接
域名分片
正向代理和反向代理
正向代理
工作在客户端的代理为正向代理。
使用正向代理的时候,需要在客户端配置需要使用的代理服务器,正向代理对服务端透明。
比如抓包工具Fiddler、Charles以及访问一些外网网站的代理工具都是正向代理
正向代理通常用于
- 缓存
- 屏蔽某些不健康的网站
- 通过代理访问原本无法访问的网站
- 上网认证,对用户访问进行授权
反向代理
工作在服务端的代理称为反向代理。使用反向代理的时候,不需要在客户端进行设置,反向代理对客户端透明。如Nginx就是反向代理
反向代理通常用于:负载均衡、服务端缓存、流量隔离、日志