应用层协议——HTTP协议

一.  概述

1. 超文本传送协议HTTP,它是一种规定了浏览器和服务器之间互相通信的规则;

2. 基于TCP,无状态(对于事务处理没有记忆能力);

3. 主要过程

       HTTP协议工作的主要过程如下图所示,HTTP协议需要和服务器建立TCP连接,这需要三次握手。而在第三次握手时,客户端将请求报文发给服务端,服务端直接回复响应报文。传输完成后,释放TCP连接。

二. HTTP/1.0与HTTP/1.1

1. HTTP/1.0的主要缺点

       每次请求一个文档都需要两倍RTT的开销。同时万维网客户和服务器每次都需要建立新的TCP连接(会分配缓存和变量),加大服务器的负担(还好浏览器每次能并行打开5-10个TCP连接,使用并行TCP连接可以缩短响应时间)。

2. HTTP/1.1

       使用了持续连接。万维网服务器可以在发送响应后的一段时间内维持该连接,使同一个客户的后续请求可以继续在这条连接上使用。最后,HTTP1.1有两种工作方式:流水线方式和非流水线方式。

<1> 非流水线方式:客户收到前一个响应才能继续发下一个请求。因此客户每访问一次对象都需要用去一个RTT。虽然比非持续连接的2个RTT好,但是缺点是服务器发送完一个对象后,TCP连接就处于空闲状态,浪费服务器资源;

<2> 流水线方式:客户在收到HTTP响应报文之前就能连续发送新的请求。因此客户访问所有对象只需要花费一个RTT时间。这种方式节省了TCP连接的空闲时间,提高下载文档效率;

三. HTTP报文

       下面介绍HTTP报文的组成部分,无论是HTTP请求报文,还是HTTP响应部分,都分为三部分:开始行(请求行,状态行),头部(请求头部,响应头部),实体(请求实体,响应实体)。

1. HTTP请求报文

<1> 请求行:包括请求方法,请求URL,HTTP协议版本三个字段组成,用空格隔开;

<2> 请求头部:由关键字/值组成,也就是key/value,每行一对,key和value用冒号隔开;

<3> 空行:最后一个请求头之后是一个空行,通知服务器以下不会再有请求头部;

<4> 请求数据:一般在post方法中使用,POST一般适用于客户需要填写表单的场合;

2. HTTP响应报文

<1> 状态行:包括HTTP协议版本,状态码,用空格隔开;

<2> 响应头部:由关键字/值组成,也就是key/value,每行一对,key和value用冒号隔开;

<3> 空行:最后一个响应头部之后是一个空行,通知服务器以下不会再有响应头部;

<4> 响应数据:服务器返回的数据;

四. HTTP状态码

HTTP协议里面定义了五种类型的状态码,分别从1XX到5XX。

1. 1XX:表示提示信息

100:提示客户端应当继续发送请求;

2. 2XX:表示成功

200:请求成功;

202:已接受,但尚未处理完成;

3. 3XX:表示重定向

301:永久重定向。新的请求要使用新的URL;

302:临时重定向。资源只是临时移动,还需要使用原来的URL;

4. 4XX:表示客户端错误

400:语法错误;

404:请求的资源未找到;

5. 5XX:表示服务器端错误

500:服务器错误;

502:坏的网关请求。作为网关或者代理服务器尝试执行请求时,从远程服务器接收到了一个无效响应;

五. HTTP缓存

在HTTP协议中定义了缓存机制,那么HTTP是如何进行缓存的?

1. Pragma

<1> 在 HTTP/1.0 时代,给客户端设定缓存方式可通过两个字段 Pragma 和 Expires,虽然这两个字段早可抛弃,但为了做 HTTP 协议的向下兼容,你还是可以看到很多网站依然带上这两个字段;

<2> 在响应报文中当该字段值为 "no-cache" 的时候,会通知客户端不要对该资源进行缓存,每次都得向服务器发一次请求才行;

2. Expires

<1> 有了 Pragma 来禁用缓存,那如果需要设置缓存的话就得有个东西来设置缓存的时间,对于 HTTP/1.0 来说,Expires 就是做这件事的;

<2> Expires 的值对应一个 GMT (格林尼治时间),比如 “Mon, 22 Mar 2017 11:12:01 GMT” 来告诉浏览器资源缓存过期时间,如果还没有超过该时间点则不发请求,直接返回 200 OK。(from cache);

<3> 当两者一起使用时候,Pragma 优先级更高,即当 Pragma 设置禁用缓存时,又给 Expires 定义一个还未到期的时间,会发现仍然会发送新的请求;

补充:Expires的缺点

现在不提倡这样的方式,因为它有两个致命的缺点:

<1> Expires 定义的缓存时间是相对于服务器上的时间而言的,而浏览器在判断的时候是基于客户端的系统时间的,如果用户修改了自己电脑的系统时间,那么这个缓存时间将没有任何意义;

<2> 假如客户端上某个资源缓存时间过期了,但此时其实服务器并没有更新过该资源,那么这时候客户端要求服务器重新把东西再发送过来一遍,会浪费带宽和时间,这显然是不合理的,我们需要有一种正确的机制用来判断东西到底可以直接使用缓存;

3. Cache-Control

<1> HTTP/1.1,在请求头中可以设置Cache-Control来定义缓存过期时间;

Cache-Control:max-age=3600,must-revalidate

表示从服务器获取的资源有效时间为1小时,在后续1小时内用户请求该资源无需发送新的请求。

Cache-Control:no-cache,no-store

表示告诉浏览器不使用缓存,每次请求都要向服务器发送请求,并且内容都不会保存到缓存或者临时文件中。

4. Last-Modified

<1> 为了解决前面遗留下的第二个问题,来保证当客户端上某个资源保存的缓存时间过期了,但这时候其实服务器并没有更新过这个资源,服务器能够正确处理这样的请求,而不是重新发送资源,让客户端与服务器之间能实现缓存文件是否更新的验证、提升缓存的复用率;

<2> HTTP/1.1新增的首部字段;

<3> 服务器将资源传递给客户端时,会将资源最后更改的时间以 "Last-Modified: GMT" 的形式加入到响应报头上一起返回给客户端。客户端会为资源标记上该信息,下次再次请求时,会把该信息附带在请求报文中发送,若传递的值与服务器上该资源的最终修改时间一致,则说明该资源没有被修改过;

补充:Last-Modified的缺陷

       如果在服务器上,一个资源被修改了,但其实际内容根本没发生改变,会因为 Last-Modified 时间匹配不上而返回了整个实体给客户端(即使客户端缓存里有个一模一样的资源)。

5. Etag

<1> 为了解决上述 Last-Modified 可能存在的不准确的问题;

<2> HTTP/1.1新增的首部字段;

<3> 服务器通过某种算法,给资源计算得出一个唯一标志符(比如 md5 标志),在把资源响应给客户端的时候,会在响应报文中加上 "Etag: 唯一标识符" 返回给客户端。客户端会保存该 Etag 字段,并在下次请求的时候将其作为请求头某字段的值发送请求,服务器只需要比较客户端传来的 Etag 跟自己服务器上该资源的 Etag 是否一致,就可以很好地判断资源相对客户端而言是否被修改过了;

六. HTTP与HTTPS

       安全套接字层超文本传输协议HTTPS,是为了数据传输的安全,而在HTTP的基础上加入了SSL协议,SSL依靠证书来验证服务器的身份,并为浏览器和服务器之间的通信加密。关于HTTPS协议的详细内容,将在下节介绍。

七. 总结

1. 超文本传送协议HTTP,规定了浏览器和服务器之间互相通信的规则,它基于TCP协议,无状态,需要三次握手建立连接;

2. 针对HTTP/1.0 每次请求一个文档都需要两倍RTT开销的主要缺点,HTTP/1.1使用了持续连接;

3. HTTP1.1有两种工作方式:流水线方式和非流水线方式。流水线方式节省了TCP连接的空闲时间,提高下载文档效率;

4. HTTP报文分为三部分:开始行(请求行,状态行),头部(请求头部,响应头部),实体(请求实体,响应实体);

5. HTTP协议里面定义了五种类型的状态码,分别从1XX到5XX;

6. 当我们上做 HTTP 相关的应用时,推荐使用HTTP缓存。可以使用 Expires 来兼容旧的浏览器,使用 Cache-Control 来更精准地利用缓存,然后开启 ETag 跟 Last-Modified 功能进一步复用缓存减少流量;

7.  安全套接字层超文本传输协议HTTPS,在HTTP的基础上加入了SSL协议,保证了数据传输的安全;

发布了19 篇原创文章 · 获赞 20 · 访问量 5847

猜你喜欢

转载自blog.csdn.net/qq_15898739/article/details/102960294