zoukankan      html  css  js  c++  java
  • HTTP 协议入门

    早上看了阮一峰老师写的 " HTTP 协议入门 ",总结一下。

    一、HTTP

    HTTP 协议(无状态协议)是基于 TCP/IP 协议的应用层协议,规定了客户端与服务端的通信格式,一般用 80 端口。

    无状态:减少服务器的 CPU 及内存资源的消耗。但是不对之前发生过的请求和响应的状态进行管理。

    解决方法:引入 Cookie。客户端首次发送请求,收到响应报文内的叫做 Set-Cookie 的首部字段信息,保存 Cookie,下次请求时,自动在请求报文中加入 Cookie 值后发送出去。服务器端收到 Cookie,检查是从哪个客户端发来的请求,对比记录,得到之前的状态信息。

     

    HTTP 的缺点

    • 通信使用明文,内容可能被窃听
    • 不验证通信双方的身份,可能遭遇伪装
    • 无法证明报文的完整性,可能造篡改

    为什么不一直使用 HTTPS

    因为与纯文本通信对比,加密通信会消耗更多的 CPU 及内存资源。所以,非敏感信息使用 HTTP 通信。

    二、HTTP/0.9

    • 1991 年 5 月发布,只有一个 GET 命令
    • 服务端只能回复 HTML 格式的字符串,并且发送回应之后就关闭 TCP 连接。

     

    三、HTTP/1.0

    • 1996 年发布,增加了 POST 命令和 HEAD 命令
    • 任何格式的内容都可以传输,包括图像,视频二进制文件等。
    • 请求和回应的格式:除了数据部分,增加头文件,描述元数据
    • 另外增加的部分:状态码(status code)、多字符集支持、多部分发送(multi-part type)、权限(authorization)、缓存(cache)、内容编码(content encoding)等。

    请求格式

    GET / HTTP/1.0
    User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5)
    Accept: */*

     

    回应格式

    HTTP/1.0 200 OK   //协议版本 + 状态码(status code) + 状态描述
    Content-Type: text/plain  //回应的数据的格式,可以自定义类型
    Content-Length: 137582
    Expires: Thu, 05 Dec 1997 16:00:00 GMT
    Last-Modified: Wed, 5 August 1996 15:55:28 GMT
    Server: Apache 0.84
    
    <html>
      <body>Hello World</body>
    </html>

     

    缺点

    每个 TCP 连接只能发送一个请求,发送数据完成之后连接就关闭,如果还想请求其他的资源,必须重新建立新的 TCP 连接。

    解决该缺点的一个方法

    有的浏览器在请求的时候,使用 Connection 字段,要求服务器不关闭 TCP 连接,以便其他请求复用,服务器同样回应同样的字段:

    Connection: keep-alive 

    四、HTTP/1.1

    • 1997 年 1 月发布。
    • 增加了持久连接(persistent connection),客户端和服务器在一段时间没有活动就关闭连接,规范的做法是:在最后一个请求是加入" Connection: close " 字段,明确请求服务器关闭 TCP 连接。
    • 增加管道机制(pipelining),在用一个 TCP 连接里,客户端可以同时发送多个请求。但是服务器还是按照顺序回应请求。
    • " Content-Length: 3495 " 字段,用来区分该数据属于哪个回应,例如本次回应 3496 个字节,后面的字节属于下一个回应。但是前提条件是,服务器发送回应之前,必须知道回应的数据长度。
    • 分块传输编码(chunked transfer encoding):" Transfer-Encoding: chunked " 字段。在每个数据块之前都有一个16进制的数值,表示此块的长度,最后一个数据块长度为 0,这样就不需要 Content-Length 字段来表示属于哪个回应。

    缺点

    虽然可以同时发送请求,但是服务器的回应依然是按照次序进行的,所以可能造成 “ 队头堵塞 ”。

    解决方法

    1、减少请求数

    2、同时多开持久连接,每个请求分开在不同的 TCP 连接里

    五、HTTP/2

    • 2015 年发布。不是 2.0 版本,因为不准备发布子版本。
    • 二进制协议:头信息和数据体都是二进制,并且统称为"帧"(frame):头信息帧和数据帧。
    • 多工:双向、同时的通信,在同一个连接里,客户端和浏览器都可以同时发送多个请求或回应,避免了"队头堵塞"。如果当前请求时间过长,先发送已处理好的部分,回应下一个请求,完成后再继续回应上一个请求。
    • 数据流(stream):每个请求或回应的所有数据包。每个数据流都有一个独一无二的编号,数据包发送的时候,都必须标记数据流ID,用来区分它属于哪个数据流。另外还规定,客户端发出的数据流,ID一律为奇数,服务器发出的,ID为偶数。而且,数据流发送中途,客户端和服务端都可以发送信号来取消这个数据流,并且不断开 TCP 连接。
    • 头信息压缩:请求的很多字段都是重复的,浪费带宽,所以,头信息使用gzipcompress压缩后再发送;另一方面,客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,以后就不发送同样字段了,只发送索引号,这样就提高速度了。
    • 服务器推送(server push):服务器未经请求,主动向客户端发送资源

     同时,在评论区看到了一个人问的问题,我回复了自己的看法,更加深了对 HTTP 的理解。

    引用王军的发言:

    阮老师,

    您在管道机制中,提到http1.1已经支持管道机制;在同一个tcp中,可以同时发送多个请求;为什么3.6缺点中却又说,在同一个tcp连接中,必须按照次序发送请求,无法同时发送?这不是自相矛盾吗?

    3.2 管道机制
    1.1 版还引入了管道机制(pipelining),即在同一个TCP连接里面,客户端可以同时发送多个请求。这样就进一步改进了HTTP协议的效率。
    举例来说,客户端需要请求两个资源。以前的做法是,在同一个TCP连接里面,先发送A请求,然后等待服务器做出回应,收到后再发出B请求。管道机制则是允许浏览器同时发出A请求和B请求,但是服务器还是按照顺序,先回应A请求,完成后再回应B请求。

    3.6 缺点
    虽然1.1版允许复用TCP连接,但是同一个TCP连接里面,所有的数据通信是按次序进行的。服务器只有处理完一个回应,才会进行下一个回应。要是前面的回应特别慢,后面就会有许多请求排队等着。这称为"队头堵塞"(Head-of-line blocking)。

    我理解是这样:管道机制下,在同一个时间点,tcp 包含多个请求,但是这些请求有先后的顺序(即使看起来好像是客户端同时发出的,但还是有先后顺序的),服务端在回应的时候就按照这种顺序一一回应。

    在您说的里面,应该是按照次序回应请求,而不是发送请求。

    个人理解。

    参考资料:HTTP 协议入门

  • 相关阅读:
    [POI2014]KUR-Couriers
    [题解向] Luogu4092 [HEOI2016/TJOI2016]树
    [探究] OI中各种初级数论算法相关
    [SCOI2005]骑士精神
    [intoj#7]最短距离
    数列分块入门
    动态规划问题基础
    Luogu P1967 货车运输
    Luogu P3379 【模板】最近公共祖先(LCA)
    Luogu P3378 【模板】堆
  • 原文地址:https://www.cnblogs.com/xiaochechang/p/5852019.html
Copyright © 2011-2022 走看看