网络协议之 - HTTP

前言

关于HTTP的知识比较繁杂,也比较零散,于是想要通过这篇文章对常用知识点进行总结,一些知识点描述是从网上搜集而来,如有侵权,可以联系我进行修改。

提出问题

  1. Http的报文结构。
  2. Http request的几种类型。
  3. Http的状态码含义。
  4. Http1.1和Http1.0的区别,以及缓存原理
  5. Http长连接keep-alive。
  6. Cookie与Session的作用于原理。
  7. 电脑上访问一个网页,整个过程是怎么样的:DNS、HTTP、TCP、OSPF、IP、ARP。

解答

1. Http的报文结构

http协议的请求报文和响应报文都是由以下4部分组成:

  1. 请求行
  2. 请求头
  3. 空行 CR + LF,回车 + 换行
  4. 请求体

2. Http request的几种类型

请求行

Request

格式:【方法 URL HTTP版本】 例如: GET /csrfToken HTTP/1.1

HTTP版本:目前有 HTTP/1.0、HTTP/1.1、HTTP/2.0 版本,其中 HTTP1.1 版本使用较广泛

方法 说明 支持HTTP协议版本
GET 获取资源 1.0 、1.1
POST 传输实体主体 1.0、1.1
PUT 传输文件 1.0、1.1
HEAD 获得报文首部 1.0、1.1
DELETE 删除资源 1.0、1.1
OPTIONS 询问支持的方法 1.1
TRACE 追踪路径 1.1
CONNECT 要求用隧道协议连接代理 1.1
LINK 建立和资源之间的联系 1.0
UNLINK 断开连接关系 1.0

Response

格式:【HTTP版本 状态码 描述】 例如: HTTP/1.1 200 OKHTTP/1.1 404 NOT FOUND

  类别 原因短语
1xx Informational(信息性状态码) 接收的请求正在处理
2xx Success(成功状态码) 请求正常处理完毕
3xx Redirection(重定向状态码) 需要进行附加操作以完成请求
4xx Client Error(客户端错误状态码) 服务器无法处理请求
5xx Server Error(服务器错误状态码) 服务器处理请求出错

3. Http的状态码含义

常用状态码
  • 200:OK,请求被正常处理
  • 204:No Content,请求被受理但没有资源可以返回,返回204响应,浏览器显示的页面不发生更新
  • 206:Partial Content,客户端进行范围请求,服务器成功执行了这部分的GET请求,响应报文中包含由Content-Range指定范围的实体内容
  • 301:Moved Permanently,永久性重定向,比如访问http://test.zhixue.com/zbptadmin,服务器会返回301,response的headers中会包含一个字段:Location: http://test.zhixue.com/zbptadmin/,浏览器会按照这个地址重新请求,并且如果用户保存了书签,浏览器会自动按照Location更新书签
  • 302:Found,临时性重定向,和301类似,但是浏览器不会更新书签
  • 303:See Other,和302类似,但303明确表示客户端应该使用GET方法获取Location资源
  • 备注:当301,302,303响应状态码返回时,几乎所有的浏览器都会把POST改成GET,并删除请求报文内的主体,之后请求会自动再次发送。301,302标准是禁止将POST方法改成GET方法的,但实际使用时浏览器厂商都会这么做。
  • 304:Not Modified,发送附带条件的请求时,(附带条件的请求是指采用GET方法的请求报文中包含If-Match,If-Modified-Since,If-None-Match,If-Range,If-Unmodified-Since中任一首部),条件不满足返回304,可直接使用客户端缓存,与重定向无关
  • 307:Temporary Redirect,临时重定向,与302类似,只是强制要求使用POST方法
  • 400:Bad Request,请求报文中存在语法错误,服务器无法识别
  • 401:Unauthorized,请求需要认证
  • 403:Forbidden,请求对应的资源禁止被访问
  • 404:Not Found,服务器无法找到对应资源
  • 500:Internal Server Error,服务器内部错误
  • 503:Service Unavailable,服务器正忙

常见HTTP首部字段

通用首部字段(请求报文与响应报文都会使用的首部字段)

  • Date:创建报文的时间
  • Connection:连接的管理
  • Cache-Control:缓存的控制
  • Transfer-Encoding:报文主题的传输编码方式

请求首部字段(请求报文会使用的首部字段)

  • Host:请求资源所在的服务器
  • Accept:可处理的媒体类型
  • Accept-Charset:可接收的字符集
  • Accept-Encoding:可接收的内容编码
  • Accept-Language:可接收的自然语言

响应首部字段(响应报文会使用的首部字段)

  • Accept-Range:可接收的字节范围
  • Location:让客户端重定向到的URI
  • Server:HTTP服务器的安装信息

实体首部字段(请求报文与响应报文的实体部分使用的首部字段)

  • Allow:资源可支持的HTTP方法
  • Content-Type:实体主类的类型
  • Content-Encoding:实体主体适用的编码方式
  • Content-Language:实体主体的自然语言
  • Content-Length:实体主体的字节数
  • Content-Range:实体主体的位置范围,一般用于发出部分请求时使用

4. HTTP1.0、HTTP1.1、HTTP2.0区别

HTTP1.0 和 HTTP1.1 主要区别

  1. 长连接

    • HTTP1.0需要使用keep-alive参数告知服务器要建立一个长连接,而HTTP1.1默认支持长连接
    • HTTP是基于TCP/IP协议的,创建一个TCP连接是需要经过三次握手的,有一定的开销,如果每次通讯都要重新建立连接的话,对性能有影响。因此最好能维持一个长连接,可以用这个长连接来发送多个请求
  2. 节约带宽

    • HTTP1.1支持只发送header信息,也就是HTTP的HEAD Method,如果服务器认为客户端有权限请求服务器,则返回100,否则返回401。客户端如果接收到100,才开始把请求体body发送到服务器。
    • 这样,当服务器返回401的时候,客户端就可以不用发送请求体了,节约了带宽
    • HTTP1.1支持分块传输,比如206状态码,由Content-Range指定传输内容,这是支持文件断点续传的基础。
  3. HOST域

    • 现在一台服务器上可以有多个虚拟主机,这些虚拟站点可以共享同一个ip和端口,HTTP1.0是没有host域的,HTTP1.1才支持这个参数

HTTP1.1 和 HTTP2.0的区别

  1. 多路复用

    • HTTP2.0使用了多路复用的技术,做到同一个连接并发处理多个请求,而且并发请求的数量比HTTP1.1大了好几个数量级

      • 当然HTTP1.1也可以多建立几个TCP连接,来支持处理更多并发的请求,但是创建TCP连接本身也是有开销的
      • TCP连接有一个预热和保护的过程,先检查数据是否传送成功,一旦成功过,则慢慢加大传输速度。因此对应瞬时并发的连接,服务器的响应就会变慢。所以最好能使用一个建立的连接,并且这个连接可以支持瞬时并发的请求
      • HTTP/1.1,若干个请求排队串行化单线程处理,后面的请求等待前面请求的返回才能获得执行机会,一旦有某个请求超时,后续请求只能被阻塞,也就是人们常说的线头阻塞
      • HTTP/2.0,多个请求可同时在一个连接上并行执行,某个任务耗时严重,不会影响到其他连接的正常执行
  2. 数据压缩

    • HTTP1.1不支持header数据的压缩,HTTP2.0使用HPACK算法对header的数据进行压缩,这样数据体积小了,在网络上传输就会更快
  3. 服务器推送

    • 当我们对HTTP2.0的web server请求数据的时候,服务器会顺便把一些客户端需要的资源一起推送到客户端,免得客户端再次创建连接发送请求到服务器获取。这种方式非常适合加载静态资源。
    • 服务器推送的这些资源其实存在客户端的某个地方,客户端直接从本地加载这些资源就可以了,不用走网络,速度自然快很多。

HTTP缓存

缓存分类

  • 强缓存

浏览器在加载资源时,先根据这个资源的一些http header判断它是否命中强缓存,如果命中,浏览器直接从自己的缓存中读取资源,不会发请求到服务器,此时状态码是200,但是看Size项是from memory cache或from disk cache

  • 协商缓存
  • 当强缓存没有命中时,浏览器一定会发送一个请求到服务器,通过服务器端依据资源的另外一些http header验证这个资源是否命中协商缓存,如果命中,服务器会将这个请求返回304,但是不会返回这个资源的数据,而是告诉客户端可以直接从缓存中加载这个资源,于是浏览器就又会从自己的缓存中去加载这个资源;如果没有命中,则将资源返回客户端,状态为200,浏览器同时依据response header中的相关项更新本地缓存数据

from memory cache 和 from disk cache

区别
  1. from memory cache 是从内存中读取缓存资源,很快,关闭浏览器后,内存中的资源就消失了
  2. from disk cache 是从磁盘中读取缓存资源,要比 from memory cache 慢,但是持久化,关闭浏览器后仍然存在
哪些资源存在memory,哪些资源存在disk

看了一些文章,大部分观点是说:

  1. 资源在disk和memory中都会存
  2. 当关闭浏览器,再打开那个页面的时候,从disk cache中获取缓存资源,同时将缓存资源存在了内存中,当再次刷新页面的时候,就从memory cache中读取,因为这样会更快一些
  3. 我自己试了一些页面,再次刷新还是有的from disk cache,有的from memory cache,网站被黑,所以这个持保留观点
  4. 还有的文章说css文件存在disk中,js等脚本存在memory中,个人认为这个不太靠谱,因为memory中的缓存在关闭浏览器就消失了,如果js只存在memory,就起不到缓存的作用了

强缓存相关http header

  • Expires

Expires的值是服务端返回的到期时间,用GMT格式的字符串表示,如:Expires: Thu, 31 Dec 2016 23:55:55 GMT。即下一次请求时,请求时间小于服务器返回的到期时间,直接使用缓存数据。不过Expires是HTTP1.0的东西,现在浏览器默认使用HTTP1.1,所以它的作用基本忽略。另一个问题是,到期时间是由服务器生成的,但是客户端时间可能和服务器时间有偏差,这就会导致缓存命中的误差。所以HTTP1.1的版本中,使用Cache-Control替代。

  • Cache-Control

Cache-Control是最重要的规则。常见的取值有:

- ```private```:客户端可以缓存
- ```public```:客户端和代理服务器都可以缓存
- ```max-age=xxx```:缓存的内容将在xxx秒后失效,单位是秒
- ```no-cache```:需要使用**协商缓存**来验证缓存数据
- ```no-store```:不缓存

协商缓存相关http header

第1组:Last-Modified/If-Modified—Since

  • Last-Modified:第一次请求资源时,服务器返回的http header,告诉浏览器资源的最后修改时间,为GMT格式,如Last-Modified: Thu, 24 Jan 2017 23:55:55 GMT
  • If-Modified-Since:再次请求服务器资源时,浏览器设置在请求header中,值 为该资源第一次请求时服务器设置的Last-Modified`值,如If-Modified-Since: Thu, 24 Jan 2017 23:55:55 GMT,服务器收到请求后发现request header中有If-Modified-Since,则与被请求资源的最后修改时间进行比对。若资源的最后修改时间大于If-Modified-Since,说明资源又被改动过,则返回资源内容,状态码200,同时浏览器依据相应response header更新缓存资源;若资源的最后修改时间小于或等于If-Modified-Since,说明资源无新修改,则返回状态码304,但是不返回资源,告知浏览器继续使用所保存的cache

第2组:Etag/If-None-Match

  • Etag:服务器响应请求时,告诉浏览器当前资源在服务器的唯一标识(生成规则由服务器确定),如Etag: W/"5886c231-8d9"
  • If-None-Match:再次请求服务器时,通过此字段告知服务器该资源的唯一标识,如If-None-Match: W/"5886c231-8d9",服务器收到请求后发现request header中有If-None-Match,则与被请求资源的唯一标识进行比对,若不同,说明资源又被改动过,则返回资源内容,状态码200,同时浏览器依据相应response header更新缓存资源;若相同,则说明资源无更改,返回304,告知浏览器继续使用所保存的缓存资源

为什么要有Etag?

Last-Modified颗粒度是秒,只能记录秒级的修改,比如1s内修改了N次,If-Modified-Since就无法判断了,所以要引入Etag。

总结

  1. 先执行强缓存策略,服务器通知浏览器一个缓存有效时间,在有效时间内,下次请求时直接使用缓存,不发起http请求,缓存从from memory cache或from disk cache中读取,若超过了有效时间,则执行协商缓存策略
  2. 对于协商缓存,将缓存信息中的Etag和Last-Modified的值通过If-None-Match和If-Modified-Since发送给服务器,由服务器进行校验,若资源无更改,返回304,浏览器继续使用缓存,若资源被更改,则返回资源,状态码200,同时浏览器更新缓存

流程图

浏览器第一次请求:

浏览器第二次请求:

5. Http长连接keep-alive

三个概念

  1. 短连接

所谓短连接,就是每次请求一个资源就建立连接,请求完成后立马关闭。每次请求都经过“创建TCP连接 -> 请求资源 -> 响应资源 -> 释放连接”。

  1. 长连接

所谓长连接(persistent connection),就是只建立一次TCP连接,多次HTTP请求都复用该连接。

  1. 并行连接

所谓并行连接(multiple connection),其实就是并发的短连接。

keep-alive

在HTTP/1.0里,为了实现client到web-server能支持长连接,必须在HTTP请求头里显式指定Connection: keep-alive

在HTTP/1.1里,就默认开启了keep-alive,要关闭keep-alive必须在HTTP请求头里显式指定Connection: close

现在大多数浏览器都默认是使用HTTP/1.1,所以keep-alive都是默认打开的。一旦client和server达成协议,那么长连接就建立好了。

keepalive_timeout

Httpd守护进程,一般都提供了keep-alive timeout时间设置参数。比如nginx的keepalive_timeout,和Apache的KeepAliveTimeout。这个keepalive_timout时间值意味着:一个http产生的tcp连接在传送完最后一个响应后,还需要hold住keepalive_timeout秒后,才开始关闭这个连接。Nginx配置中的keepalive_timeout默认为75s,

6. cookie与Session

这个重点在于理解,这里就不赘述了。

猜你喜欢

转载自www.cnblogs.com/asd667/p/9811850.html