HTTP协议介绍三

225 阅读7分钟

一、HTTP传输管理

HTTP报文是由header+body组成的,header涉及到规范和标准的制定,也是为更好的传输body提供前置条件,不同body对应的数据类型以及语言类型都不一样,如何对body实现更有效的传输管理。

1.1、传输实体数据的定义

HTTP协议是应用层的协议,数据从一端传输到另一端只能说完成了一半工作,还必须要告诉上层应用这是什么数据才行,否则应用层完全就是不知所措。

HTTP采用了早期电子邮件定义数据的方案MIME,用来标记body的数据类型(MIME type),常见的类别如下:

  1. text:文本格式的可读数据
  2. image:图像文件
  3. audio/vedio:音频和视频数据
  4. application:数据格式不固定,可能是文本也可能是二进制。application/json, application/javascript, application/pdf...

HTTP在传输时为了节省带宽,有时候还会压缩数据,需要定义Encoding type,告诉数据采用的编码格式,这样接收方才能正确解压缩,常见的压缩方式如下:

  • gzip:GNU zip压缩格式
  • deflate:zlib压缩格式
  • br:一种专门为HTTP优化的新压缩算法

基于MIME type和Encoding type, 浏览器和服务端的header定义数据的方式如下:

  • Accept:标记客户端可理解的MIME type
  • Content-Type:标记服务器响应实体数据真实类型
  • Accept-Encoding:客户端支持的压缩格式
  • Content-Encoding:服务端响应实体数据实际压缩格式

HTTP的语言类型主要是解决HTTP国际化的问题,客户端采用Accept-Language和Accept-Charset标识,服务端采用Content-Language和charset来标识。

1.2、大文件如何传输

采用压缩和分块传输的方式,解决大文件传输的问题,这样网络就不会被大文件长时间占用,内存,带宽等资源就节省下来了。

HTTP协议的响应报文里采用头字段 Transfer-Encoding:chunked 来表示报文里的body不是一次性发过来的,而是分成许多的块逐个发送。响应如下图所示:

image.png

二、HTTP连接管理

HTTP的连接管理也算是一个老生长谈的话题,经常听到各种长连接,短连接之类的名词。下面也算是总结和梳理下以前的知识

2.1、短连接和长连接

HTTP底层的数据传输基于TCP/IP, 每次发送请求前需要和服务器建立好连接,收到响应报文后会立即关闭连接。如果客户端和服务器的整个连接过程很短暂,不会与服务器保持长时间的连接状态,那这样的连接就是“短连接”,早期HTTP协议也被成为“无连接”协议。

短连接的缺点相当严重,在TCP协议中建立连接和关闭连接都是非常昂贵的操作,如果做一个简单的请求-响应就进行一次连接,传输效率就会严重降低。

针对短连接暴露出来的缺点,HTTP协议就提出了“长连接”的通信方式。解决的方式也很简单,就是把TCP的连接和关闭非常耗时间的成本,均摊到多个请求-应答上,让请求-应答集中的HTTP通信共用同一个TCP连接。

服务端支持长连接的标识是:Connection: keep-alive. 不管客户端是否显式要求长连接,只要服务端支持长连接都会在响应报文里加上。客户端,在请求头里加上 Connection: close 可以主动关闭连接。

2.2、连接重定向

在我们浏览某些网页时,由于没有用户名和密码,网站经常会给我们重定向到登录页面,进行登录验证。

这样的跳转动作是由浏览器使用者主动发起,称为“主动跳转”;如果是服务器来发起,浏览器使用者无法控制,也就称为“被动跳转”,在HTTP协议里面称为“重定向”。

重定向标识: 服务器在进行响应时,会出现一个新的头字段:Location: /index.html, 标记服务器要求重定向的URI

重定向状态码:301和302. 301:永久重定向,302:临时重定向

三、HTTP的Cookie管理

HTTP无状态,既是优点又是缺点。优点是服务器没有状态差异,缺点是无法支持需要记录状态的事务操作。Cookie技术,给HTTP增加了记忆能力。

HTTP用到如下两个字段来提供Cookie能力,响应头字段Set-Cookie和请求头字段Cookie.

当用户第一次访问服务器时,服务器给其创建一个独特的身份标识数据,格式是key=value,放入Set-Cookie字段,下次用户再请求的时候,这个值自动放进Cookie字段里发给服务器。

Cookie的属性

  • Expires: 过期时间
  • Max-Age:相对过期时间=浏览器收到报文的时间点+Max-Age,浏览器会优先采用Max-Age
  • Domain, Path: 指定Cookie所属域名和路径
  • HttpOnly: 此Cookie只能通过浏览器HTTP协议传输

四、HTTP的缓存管理

网络时延,链路漫长,使得浏览器使用HTTP获取资源的成本较高,所以,需要把获取到来之不易的数据缓存起来,下次再请求时,尽可能地复用,节约网络带客,加快响应速度。

4.1、服务端缓存控制

服务器标记资源有效期使用的头字段是“Cache-Control”,经常使用如下属性进行控制。

  • max-age: 资源的生存时间,时间起点是从服务端响应报文的创建时刻开始计算
  • no-store:不允许缓存,用于非常频繁变化的数据
  • no-cache:可以缓存,使用之前必须要去服务器验证是否过期,是否由最新的版本
  • must-revalidate:缓存不不过期就可以继续使用,过期了还想用就必须取服务器验证

4.2、客户端缓存控制

除了和服务端有一样能力进行缓存控制,客户端还常用的条件请求进行缓存控制。字段是 if-Modified-Since 和 If-None-Match, 需要第一次的响应报文预先提供Last-modified和ETag两个字段。

Last-modified:文件最后的修改时间

ETag:资源的一个唯一标识,主要是用来解决时间无法准确区分文件变化的问题

if-Modified-Since和Last-modified: 解决查看资源最近修改时间,如果时间有最新的则重新否则,否则使用本地缓存

If-None-Match和ETag:验证资源是否有变动,没有使用缓存。

4.3、代理缓存控制

代理:服务本身不生产内容,而是处于中间位置转发上下游的请求和响应,具有双重身份。

面向下游的用户时,表现为服务器,代表源服务器响应客户端的请求;而面向上游的源服务器时,又表现为客户端,代表客户端发送的请求。加入代理后,缓存的控制也有相应的改动。

4.3.1、源服务器的缓存控制

区分客户端上缓存和代理上的缓存,使用private和public

  • private: 缓存只能在客户端保存,是用户“私有”的,不能放在代理上和别人共享
  • public:缓存完全开放,谁都可以用

must-revalidate:只要过期就必须回源服务器验证,proxy-revalidate 只要求代理的缓存过期后必须验证,客户端不必回源。

s-maxage:只限定在代理上能够存多久,而客户端仍然使用max-age

4.3.2、客户端的缓存控制

max-stale: 如果代理上的缓存过期了也可以接受,但不能过期太多,超过x秒也会不要

min-fresh: 缓存必须有效,而且必须在x秒后依然有效

only-if-cached:只接受代理缓存的数据,不接受源服务器的响应