HTTP
Last updated
Last updated
HTTP(HyperText Transfer Protocol,超文本传输协议)是建立在应用层的协议,是万维网数据通信的基础,负责服务器到客户端之间的数据传输。一般模式是客户端发送请求,服务器响应客户端发送的请求来完成数据交互。HTTP并没有规定必须使用它的层或它支持的层,尽管TCP/IP协议栈目前使用最多,但是任何能够提供可靠传输的协议都可以被使用。
采用客户端/服务器的模式
HTTP最初的设计目的是提供一种发布和接受HTML页面的方法,所以HTTP是无连接无状态的协议。
HTTP对传输的数据类型没有限制,使用灵活。
HTTP协议的默认端口是80。
HTTP采用B/S模式,客户端发出请求,服务器响应请求。
在浏览器的地址栏输入www.google.com
会发生什么呢?有哪些工作在我们看不见的地方进行呢?
第一步:地址解析
当浏览器拿到www.google.com
这个url时,并不知道应该去哪里请求资源。所以会发出DNS请求解析这个url,获得服务器的IP地址。
第二步:封装HTTP请求报文
拿到主机IP地址后,浏览器会把请求url的协议、主机号、端口号和资源路径结合本机的信息封装成一个HTTP请求包。
第三步:封装TCP包,建立TCP连接
在HTTP到达TCP后,TCP需要先和服务器建立连接,建立连接时采用TCP三次握手的方式。当TCP建立好连接之后,将收到的HTTP报文加上TCP报文的首部信息,组装成新的TCP报文。
第四步:客户端发送请求
此时,客户端发送一个请求给服务器,请求的信息主要包括统一资源标识符,版本协议号以及MIME信息。
第五步:服务器响应
服务器收到请求,经过处理后会返回响应信息,主要包括状态行、协议版本号和状态码、MIME信息等。
第六步:关闭TCP连接
一般情况下,服务器返回响应后会关闭TCP连接。但是如果在浏览器或服务器的头部信息中加入Connection:keep-alive
后,TCP连接将会保持到会话结束。保持连接的做法节省了每次请求建立连接的时间和带宽成本。
基本有状态行、请求头和正文信息组成。
请求信息
响应报文
HTTP/1.1协议中定义了八种方法来操作指定资源
方法名
主要用途
GET
像指定的资源发出“显式”请求,只会读取数据,不会产生副作用
HEAD
请求资源的元信息或元数据
POST
向指定资源提交数据,请求服务器处理
PUT
向指定资源上传最新内容
DELETE
请求服务器删除URI指定的资源
OPTIONS
请求该资源支持的HTTP方法
CONNECT
HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器
GET和POST请求的区别
1.GET在浏览器回退时是无害的,而POST会再次提交请求。
2.GET请求的url地址可以被保存到书签,而POST不可以。
3.GET请求会被浏览器主动cache,而POST不会,除非手动设置。
4.GET请求只能进行URL编码,而POST支持多种编码方式。
5.GET请求参数会保留在浏览器历史记录里,而POST参数不会被保留。
6.GET请求在URL中传送的参数是有长度限制(4k,IE是2k)的,而POST没有。
7.GET只接受ASCII字符,而POST没有限制。
8.POST比GET更安全,因为GET的参数直接暴露在URL上,所以不能用来传递敏感信息。
9.GET的参数通过URL传递,POST的参数放在body中。
10.GET产生一个TCP数据包,POST产生两个TCP数据包(firefox只发送一次)。
条件GET
HTTP条件GET时HTTP协议为了减少不必要的带宽浪费,提出的一种方案。当客户端之前已经访问过某网站,并打算再次访问网站时,客户端向服务器发一个包询问是否在上一次访问网站的时间后修改了页面,如果没有更新,就继续使用本地缓存,如果发生了更新则返回更新后的网页。下面是一个实例:
编码格式
作用
application/x-www-form-urlencoded
默认提交方式,提交的数据按照key1=value1&key2=value2的方式编码,key和value都进行了URL转码
multipart/form-data
上传文件时使用的方式
application/json
传输主体是序列化后的JSON字符串
text/xml
传输主体是xml格式的内容
所有HTTP响应的第一行都是状态航,分别是HTTP协议版本号,3位数字组成的状态码,以及描述状态的短语,用空格隔开。
状态代码的第一个数字代表当前响应的类型:
状态码
状态消息
1XX消息
请求已被服务器接收,继续处理
2XX成功
请求已被服务器接收、理解并接受
3XX重定向
需要后续操作才能完成这一请求
4XX请求错误
请求含有语法错误或者无法被正常执行
5XX服务器错误
服务器在处理正确请求时发生错误
应该注意的几个状态码:
状态码
状态消息
200
请求成功
301
永久重定向
302
暂时重定向
304
请求成功,文件未改变,可使用缓存
401
请求未经授权
403
服务器收到请求,但是拒绝服务
404
请求失败
500
服务器发生不可预期的错误
503
服务器暂时不能处理客户端的请求
为了减少网络带宽消耗的、降低服务器压力和加快页面打开速度,HTTP缓存诞生了。
1.在HTTP报文中与缓存相关的首部
字段名称
作用
备注
Cache-Control
控制缓存的行为
http1.1产物,优先级高于Pragma、Expires
Pragma
值为'no-cache'时禁用缓存
http1.0产物,设置在客户端时仅有IE才能识别,设置在服务器响应报文首部时可禁用缓存,优先级高于Expires
字段名称
作用
备注
if-Match
比较ETag是否一致
如果没有匹配到Tag则返回412,否则忽略
if-None-Match
比较ETag是否不一致
没有匹配上需要重新发送资源,否则返回304和响应报头
if-Modified-Since
比较资源最后更新的时间是否一致
如果与服务器的最后修改时间一致,则返回304和响应报文
if-Unmodified-Since
比较资源最后更新的时间是否不一致
如果最后修改时间不一致,则返回412状态码
字段名称
作用
备注
ETag
资源的匹配信息
用于告知浏览器资源的'标识'信息
字段名称
作用
备注
Expires
实体主体的过期时间
http1.0产物,值是一个GMT时间,表示资源的过期时间,仅IE能识别,设置在响应报文首部可以在任何浏览器中作用,但时间是相对服务器时间,如果修改客户端时间则无意义
Last-Modified
资源最后一次修改的时间
标记资源最后更改的时间
2.Cache-Control
由于Expires时间是相对服务器而言,无法保证和客户端时间统一
的问题,http1.1新增了Cache-Control来指定缓存过期的时间,可用于请求报文和响应报文首部。其优先级高于Pragma和Expires。
作为请求首部时,常用的值是:
字段取值
说明
no-cache
告诉(代理)服务器不直接使用缓存,要求向原服务器发起请求
no-store
所有内容不会被保存到缓存或Internet临时文件中
only-if-cached
希望获取缓存内容,不用向原服务器去请求
max-age
缓存有效期,单位是秒
作为响应首部时,常用的值是;
字段取值
说明
public
任何情况下都得缓存该资源
private
返回报文中全部或部分数据仅开放给某些用户,指定用户可缓存
no-cache
不直接使用缓存,向服务器发起(新鲜度校验)请求
no-store
所有内容不会保存到缓存或Internet临时文件中
only-if-cached
希望获取缓存内容,不用向原服务器发起请求
must-revalidate
当前资源一定是向原服务器发去验证请求的
Cache-Control的值可以自由组合可选值,但是也有些限制,比如no-cache就不能和max-age、max-fresh、max-stale一起搭配使用。
3.缓存实践
在项目中,需要设置Expires来兼容旧的浏览器,使用Cache-Control来精准地利用缓存,然后开启ETag和Last-Modified功能进一步复用缓存较少流量。
4.资源缓存机制
以上的Expires、Cache-Control字段属于强制缓存,Last-Modified等需要验证的字段属于对比缓存。执行顺序是:
对比强制缓存,服务器通知浏览器一个缓存时间,在缓存时间内,下次请求可直接使用缓存,超过过期时间则需要执行比较缓存策略。 对于比较缓存,将缓存信息的ETag和Lsat-Modified通过请求发送给服务器,由服务器校验,返回304状态码可直接使用缓存。
5.用户操作行为与缓存
用户操作
Expries/Cache-Control
Last-Modified/Etag
地址栏回车
有效
有效
页面链接跳转
有效
有效
新开窗口
有效
有效
前进后退
有效
有效
F5刷新
无效
有效
Ctrl+F5强制刷新
无效
无效
通过上表可以发现,当用户按下F5刷新时,会忽略Expries/Cache-Control的设置,再次发送请求去服务器,而Last-Modified/Etag还是有效的,服务器会根据情况判断返回304还是200。而当用户按下Ctrl和F5进行强制刷新时,所有的缓存机制都将失效,重新从服务器拉取资源。
6.不能被缓存的请求
无法被浏览器缓存的请求:
HTTP版本
特点
改进点
HTTP/1.0
可以发送任何格式的内容,支持GET、POST、HEAD命令,增加头信息
增加了内容的格式、命令、报头
HTTP/1.1
支持持久连接、管道机制、分块传输编码,增加了五个新命令
增加了持久连接、分块传输编码和PUT、PATCH、HEAD、OPTIONS、DELETE命令
HTTP/2.0
头信息和数据体采用二进制编码,支持TCP复用,采用数据流返回数据,头信息压缩,服务器推送
支持TCP复用、服务器推送