Skip to main content

HTTP

HTTP 协议是个⽆状态协议,不会保存状态

Post 和 Get

  • Get 请求能缓存, Post 不能。
  • Post 相对 Get 安全⼀点点,因为 Get 请求都包含在 URL ⾥,且会被浏览器保存历史纪录, Post 不会,但是在抓包的情况下都是⼀样的。
  • Post 可以通过 request body 来传输⽐ Get 更多的数据, Get 没有这个技术。
  • URL 有⻓度限制,会影响 Get 请求,但是这个⻓度限制是浏览器规定的,不是 RFC 规定的。
  • Post ⽀持更多的编码类型且不对数据类型限制。

常⻅状态码

  • 3XX 重定向

    • 301 moved permanently ,永久性重定向,表示资源已被分配了新的 URL
    • 302 found ,临时性重定向,表示资源临时被分配了新的 URL
    • 303 see other ,表示资源存在着另⼀个 URL,应使⽤ GET ⽅法定向获取资源。
    • 304 not modified ,表示服务器允许访问资源,但因发⽣请求未满⾜条件的情况。
    • 307 temporary redirect ,临时重定向,和 302 含义类似,但是期望客户端保持请求⽅法不变向新的地址发出请求。
  • 4XX 客户端错误

    • 400 bad request ,请求报⽂存在语法错误。
    • 401 unauthorized ,表示发送的请求需要有通过 HTTP 认证的认证信息。
    • 403 forbidden ,表示对请求资源的访问被服务器拒绝。
    • 404 not found ,表示在服务器上没有找到请求的资源。
  • 5XX 服务器错误

    • 500 internal sever error ,表示服务器端在执⾏请求时发⽣了错误。
    • 501 Not Implemented ,表示服务器不⽀持当前请求所需要的某个功能。
    • 503 service unavailable ,表明服务器暂时处于超负载或正在停机维护,⽆法处理请求。

HTTP 头

通⽤字段作⽤
Cache-Control控制缓存的⾏为
Connection浏览器想要优先使⽤的连接类型,⽐如 keep-alive
Date创建报⽂时间
Pragma报⽂指令
Via代理服务器相关信息
Transfer-Encoding传输编码⽅式
Upgrade要求客户端升级协议
Warning在内容中可能存在错误
请求字段作⽤
Accept能正确接收的媒体类型
Accept-Charset能正确接收的字符集
Accept-Encoding能正确接收的编码格式列表
Accept-Language能正确接收的语⾔列表
Expect期待服务端的指定⾏为
From请求⽅邮箱地址
Host服务器的域名
If-Match两端资源标记⽐较
If-Modified-Since本地资源未修改返回 304(⽐较时间)
If-None-Match本地资源未修改返回 304(⽐较标记)
User-Agent客户端信息
Max-Forwards限制可被代理及⽹关转发的次数
Proxy-Authorization向代理服务器发送验证信息
Range请求某个内容的⼀部分
Referer表示浏览器所访问的前⼀个⻚⾯
TE传输编码⽅式
响应字段作⽤
Accept-Ranges是否⽀持某些种类的范围
Age资源在代理缓存中存在的时间
ETag资源标识
Location客户端重定向到某个 URL
Proxy-Authenticate向代理服务器发送验证信息
Server服务器名字
WWW-Authenticate获取资源需要的验证信息
实体字段作⽤
Allow资源的正确请求⽅式
Content-Encoding内容的编码格式
Content-Language内容使⽤的语⾔
Content-Lengthrequest body ⻓度
Content-Location返回数据的备⽤地址
Content-MD5Base64 加密格式的内容 MD5 检验值
Content-Range获取资源需要的验证信息
Content-Type内容的媒体类型
Expires内容的过期时间
Last_modified内容的最后修改时间

http ⽆状态⽆连接

  • http 协议对于事务处理没有记忆能⼒。
  • 对同⼀个 url 请求没有上下⽂关系。
  • 每次的请求都是独⽴的,它的执⾏情况和结果与前⾯的请求和之后的请求是⽆直接关系的,它不会受前⾯的请求应答情况直接影响,也不会直接影响后⾯的请求应答情况。
  • 服务器中没有保存客户端的状态,客户端必须每次带上⾃⼰的状态去请求服务器。
  • ⼈⽣若只如初⻅,请求过的资源下⼀次会继续进⾏请求。

http 协议⽆状态中的 状态 到底指的是什么?!

  • 【状态】的含义就是:客户端和服务器在某次会话中产⽣的数据。
  • 那么对应的【⽆状态】就意味着:这些数据不会被保留。
  • 通过增加 cookie 和 session 机制,现在的⽹络请求其实是有状态的。
  • 在没有状态的 http 协议下,服务器也⼀定会保留你每次⽹络请求对数据的修改,但这跟保留每次访问的数据是不⼀样的,保留的只是会话产⽣的结果,⽽没有保留会话。

http-cache:就是 http 缓存

  1. ⾸先得明确 http 缓存的好处

    • 减少了冗余的数据传输,减少⽹费
    • 减少服务器端的压⼒
    • Web 缓存能够减少延迟与⽹络阻塞,进⽽减少显示某个资源所⽤的时间
    • 加快客户端加载⽹⻚的速度
  2. 常⻅ http 缓存的类型

    • 私有缓存(⼀般为本地浏览器缓存)
    • 代理缓存
  3. 然后谈谈本地缓存

本地缓存是指浏览器请求资源时命中了浏览器本地的缓存资源,浏览器并不会发送真正的请求给服务器了。

  • 它的执⾏过程是
    1. 第⼀次浏览器发送请求给服务器时,此时浏览器还没有本地缓存副本,服务器返回资源给浏览器,响应码是 200 OK ,浏览器收到资源后,把资源和对应的响应头⼀起缓存下来。
    2. 第⼆次浏览器准备发送请求给服务器时候,浏览器会先检查上⼀次服务端返回的响应头信息中的 Cache-Control ,它的值是⼀个相对值,单位为秒,表示资源在客户端缓存的最 ⼤有效期,过期时间为第⼀次请求的时间减去 Cache-Control 的值,过期时间跟当前的请求时间⽐较,如果本地缓存资源没过期,那么命中缓存,不再请求服务器。
    3. 如果没有命中,浏览器就会把请求发送给服务器,进⼊缓存协商阶段。
tip

与本地缓存相关的头有: Cache-ControlExpiresCache-Control 有多个可选值代表不同的意义,⽽ Expires 就是⼀个⽇期格式的绝对值。

Cache-Control

tip

Cache-ControlHTTP 缓存策略中最重要的头,它是 HTTP/1.1 中出现的,它由如下⼏个值

  • no-cache :不使⽤本地缓存。需要使⽤缓存协商,先与服务器确认返回的响应是否被更改,如果之前的响应中存在 ETag ,那么请求的时候会与服务端验证,如果资源未被更 改,则可以避免重新下载。

  • no-store :直接禁⽌游览器缓存数据,每次⽤户请求该资源,都会向服务器发送⼀个请求,每次都会下载完整的资源。

  • public :可以被所有的⽤户缓存,包括终端⽤户和 CDN 等中间代理服务器。

  • private :只能被终端⽤户的浏览器缓存,不允许 CDN 等中继缓存服务器对其缓存。

  • max-age :从当前请求开始,允许获取的响应被重⽤的最⻓时间(秒)。

tip

Cache-Control: public, max-age=1000

表示资源可以被所有⽤户以及代理服务器缓存,最⻓时间为 1000 秒。

Expires

ExpiresHTTP/1.0 出现的头信息,同样是⽤于决定本地缓存策略的头,它是⼀个绝对时间,时间格式是如 Mon, 10 Jun 2022 21:31:12 GMT ,只要 发送请求时间是在 Expires 之前,那么本地缓存始终有效,否则就会去服务器发送请求获取新的资源。如果同时出现 Cache-Control:max-ageExpires ,那么 max-age 优先级更⾼。他们可以这样组合使⽤。

Cache-Control: public
Expires: Wed, Jan 10 2018 00:27:04 GMT

所谓的缓存协商

当第⼀次请求时服务器返回的响应头中存在以下情况时

  • 没有 Cache-ControlExpires
  • Cache-ControlExpires 过期了
  • Cache-Control 的属性设置为 no-cache

那么浏览器第⼆次请求时就会与服务器进⾏协商,询问浏览器中的缓存资源是不是旧版本,需不需要更新,此时,服务器就会做出判断,如果缓存和服务端 资源的最新版本是⼀致的,那么就⽆需再次下载该资源,服务端直接返回 304 Not Modified 状态码,如果服务器发现浏览器中的缓存已经是旧版本了,那 么服务器就会把最新资源的完整内容返回给浏览器,状态码就是 200 Ok ,那么服务端是根据什么来判断浏览器的缓存是不是最新的呢?其实是根据 HTTP 的另外两组头信息,分别是: Last-Modified/If-Modified-SinceETag/If-None-Match

Last-Modified 与 If-Modified-Since

  1. 浏览器第⼀次请求资源时,服务器会把资源的最新修改时间 Last-Modified:Thu, 29 Dec2022 18:23:55 GMT 放在响应头中返回给浏览器。

  2. 第⼆次请求时,浏览器就会把上⼀次服务器返回的修改时间放在请求头 If-ModifiedSince:Thu,29 Dec 2011 18:23:55 发送给服务器,服务器就会拿这个时间跟服务器上 的资源的最新修改时间进⾏对⽐。

解释

如果两者相等或者⼤于服务器上的最新修改时间,那么表示浏览器的缓存是有效的,此时缓存会命中,服务器就不再返回内容给浏览器了,同时 LastModified 头也不会返回,因为资源没被修改,返回了也没什么意义。如果没命中缓存则最新修改的资源连同 Last-Modified 头⼀起返回。

第⼀次请求返回的响应头

Cache-Control:max-age=3600
Expires: Fri, Jan 12 2020 00:27:04 GMT
Last-Modified: Wed, Jan 10 2020 00:27:04 GMT

第⼆次请求的请求头信息

If-Modified-Since: Wed, Jan 10 2020 00:27:04 GMT

这组头信息是基于资源的修改时间来判断资源有没有更新,另⼀种⽅式就是根据资源的内容来判断。

ETag 与 If-None-Match

ETag/If-None-MatchLast-Modified/If-Modified-Since 的流程其实是类似的,唯⼀的区别是它基于资源的内容的摘要信息(⽐如 MD5 hash )来 判断。

浏览器发送第⼆次请求时,会把第⼀次的响应头信息 ETag 的值放在 IfNone-Match 的请求头中发送到服务器,与最新的资源的摘要信息对⽐,如果 相等,取浏览器缓存,否则内容有更新,最新的资源连同最新的摘要信息返回。⽤ ETag 的好处是如果因为某种原因到时资源的修改时间没改变,那么 ⽤ ETag 就能区分资源是不是有被更新。

第⼀次请求返回的响应头

Cache-Control: public, max-age=31536000
ETag: "15f0fff99ed5aae4edffdd6496d7131f"

第⼆次请求的请求头

If-None-Match: "15f0fff99ed5aae4edffdd6496d7131f"

13

HTTP 的⼏种请求⽅法⽤途

  • GET ⽅法

    • 发送⼀个请求来取得服务器上的某⼀资源。
  • POST ⽅法

    • URL 指定的资源提交数据或附加新的数据。
  • PUT ⽅法

    • POST ⽅法很像,也是想服务器提交数据。但是它们之间有不同。 PUT 指定了资源在服务器上的位置,⽽ POST 没有。
  • HEAD ⽅法

    • 只请求⻚⾯的⾸部。
  • DELETE ⽅法

    • 删除服务器上的某资源。
  • OPTIONS ⽅法

    • 它⽤于获取当前 URL 所⽀持的⽅法。如果请求成功,会有⼀个 Allow 的头包含类似 GETPOST 这样的信息。
  • TRACE ⽅法

    • TRACE ⽅法被⽤于激发⼀个远程的,应⽤层的请求消息回路。
  • CONNECT ⽅法

    • 把请求连接转换到透明的 TCP/IP 通道。

HTTP request 报⽂结构是怎样的

  1. ⾸⾏是 Request-Line 包括:请求⽅法,请求 URI协议版本CRLF

  2. ⾸⾏之后是若⼲⾏请求头,包括 general-headerrequest-header 或者 entity-header, 每个⼀⾏以 CRLF 结束

  3. 请求头和消息实体之间有⼀个 CRLF 分隔

  4. 根据实际请求需要可能包含⼀个消息实体 ⼀个请求报⽂例⼦如下:

    GET /Protocols/rfc2616/rfc2616-sec5.html HTTP/1.1
    Host: www.w3.org
    Connection: keep-alive
    Cache-Control: max-age=0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,\*/
    User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML,
    Referer: https://www.google.com.hk/
    Accept-Encoding: gzip,deflate,sdch
    Accept-Language: zh-CN,zh;q=0.8,en;q=0.6
    Cookie: authorstyle=yes
    If-None-Match: "2cc8-3e3073913b100"
    If-Modified-Since: Wed, 01 Sep 2004 13:24:52 GMT
    name=qiu&age=25

HTTP response 报⽂结构是怎样的

  1. ⾸⾏是状态⾏包括:HTTP 版本,状态码,状态描述,后⾯跟⼀个 CRLF

  2. ⾸⾏之后是若⼲⾏响应头,包括:通⽤头部,响应头部,实体头部

  3. 响应头部和响应实体之间⽤⼀个 CRLF 空⾏分隔

  4. 最后是⼀个可能的消息实体 响应报⽂例⼦如下:

    HTTP/1.1 200 OK
    Date: Tue, 08 Jul 2014 05:28:43 GMT
    Server: Apache/2
    Last-Modified: Wed, 01 Sep 2004 13:24:52 GMT
    ETag: "40d7-3e3073913b100"
    Accept-Ranges: bytes
    Content-Length: 16599
    Cache-Control: max-age=21600
    Expires: Tue, 08 Jul 2014 11:28:43 GMT
    P3P: policyref="http://www.w3.org/2001/05/P3P/p3p.xml"
    Content-Type: text/html; charset=iso-8859-1
    {"name": "qiu", "age": 25}

HTTP 1.0 1.1 2.0

  • HTTP1.0

HTTP 协议的第二个版本,第一个在通讯中指定版本号的 HTTP 协议版本 HTTP1.0 浏览器与服务器只保持短暂的连接,每次请求都需要与服务器建立一个 TCP 连接 服务器完成请求处理后立即断开 TCP 连接,服务器不跟踪每个客户也不记录过去的请求简单来讲,每次与服务器交互,都需要新开一个连接。

例如,解析 html 文件,当发现文件中存在资源文件的时候,这时候又创建单独的链接最终导致,一个 html 文件的访问包含了多次的请求和响应,每次请求都需要创建连接、关系连接 这种形式明显造成了性能上的缺陷如果需要建立长连接,需要设置一个非标准的 Connection 字段 Connection: keep-alive

  • HTTP1.1

HTTP1.1 中,默认支持长连接(Connection: keep-alive),即在一个 TCP 连接上可以传送多个 HTTP 请求和响应,减少了建立和关闭连接的消耗和延迟 建立一次连接,多次请求均由这个连接完成。

1

这样,在加载 html 文件的时候,文件中多个请求和响应就可以在一个连接中传输。

同时,HTTP 1.1 还允许客户端不用等待上一次请求结果返回,就可以发出下一次请求,但服务器端必须按照接收到客户端请求的先后顺序依次回送响应结果,以保证客户端能够区分出每次请求的响应内容, 这样也显著地减少了整个下载过程所需要的时间。

  • 同时,HTTP1.1HTTP1.0 的基础上,增加更多的请求头和响应头来完善的功能,如下:

    • 引入了更多的缓存控制策略,如 If-Unmodified-Since, If-Match, If-None-Match 等缓存头来控制缓存策略。
    • 引入 range ,允许值请求资源某个部分。
    • 引入 host ,实现了在一台 WEB 服务器上可以在同一个 IP 地址和端口号上使用不同的主机名来创建多个虚拟 WEB 站点并且还添加了其他的请求方法:putdeleteoptions
  • HTTP2.0

  • 而 HTTP2.0 在相比之前版本,性能上有很大的提升,如添加了一个特性:

    • 多路复用
    • 二进制分帧
    • 首部压缩
    • 服务器推送
  • 多路复用

HTTP/2 复用 TCP 连接,在一个连接里,客户端和浏览器都可以同时发送多个请求或回应,而且不用按照顺序一一对应,这样就避免了 队头堵塞

2

上图中,可以看到第四步中 css、js 资源是同时发送到服务端

  • 二进制分帧

    • 帧是 HTTP2 通信中最小单位信息。
    • HTTP/2 采用二进制格式传输数据,而非 HTTP 1.x 的文本格式,解析起来更高效。
    • 将请求和响应数据分割为更小的帧,并且它们采用二进制编码。
    • HTTP2 中,同域名下所有通信都在单个连接上完成,该连接可以承载任意数量的双向数据流。
    • 每个数据流都以消息的形式发送,而消息又由一个或多个帧组成。多个帧之间可以乱序发送,根据帧首部的流标识可以重新组装,这也是多路复用同时发送数据的实现条件。
  • 首部压缩

    • HTTP/2 在客户端和服务器端使用“首部表”来跟踪和存储之前发送的键值对,对于相同的数据,不再通过每次请求和响应发送。
    • 首部表在 HTTP/2 的连接存续期内始终存在,由客户端和服务器共同渐进地更新。
    • 例如:下图中的两个请求, 请求一发送了所有的头部字段,第二个请求则只需要发送差异数据,这样可以减少冗余数据,降低开销。
  • 服务器推送

    • HTTP2 引入服务器推送,允许服务端推送资源给客户端。
    • 服务器会顺便把一些客户端需要的资源一起推送到客户端,如在响应一个页面请求中,就可以随同页面的其它资源。
    • 免得客户端再次创建连接发送请求到服务器端获取。
    • 这种方式非常合适加载静态资源。

3

  • HTTP1.0:
    • 浏览器与服务器只保持短暂的连接,浏览器的每次请求都需要与服务器建立一个 TCP 连接。
  • HTTP1.1:
    • 引入了持久连接,即 TCP 连接默认不关闭,可以被多个请求复用。
    • 在同一个 TCP 连接里面,客户端可以同时发送多个请求。
    • 虽然允许复用 TCP 连接,但是同一个 TCP 连接里面,所有的数据通信是按次序进行的,服务器只有处理完一个请求,才会接着处理下一个请求。如果前面的处理特别慢,后面就会有许多请求排队等着。
    • 新增了一些请求方法。
    • 新增了一些请求头和响应头。
  • HTTP2.0:
    • 采用二进制格式而非文本格式。
    • 完全多路复用,而非有序并阻塞的、只需一个连接即可实现并行。
    • 使用报头压缩,降低开销。
    • 服务器推送。

会话状态

  • session : 是⼀个抽象概念,开发者为了实现中断和继续等操作,将 userAgentserver 之间⼀对⼀的交互,抽象为 会话 ,进⽽衍⽣出 会话状态,也就是 session 的概念。

  • cookie :它是⼀个世纪存在的东⻄, http 协议中定义在 header 中的字段,可以认为是 session 的⼀种后端⽆状态实现。

    • 现在我们常说的 session ,是为了绕开 cookie 的各种限制,通常借助 cookie 本身和后端存储实现的,⼀种更⾼级的会话状态实现。

session 的常⻅实现要借助 cookie 来发送 sessionID

  • cookie ,类型为「小型文本文件」,指某些网站为了辨别用户身份而储存在用户本地终端上的数据,通过响应头 set-cookie 决定。

  • 作为一段一般不超过 4KB 的小型文本数据,它由一个名称(Name)、一个值(Value)和其它几个用于控制 Cookie 有效期、安全性、使用范围的可选属性组成。

  • Cookie 主要用于以下三个方面:

    • 会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息)
    • 个性化设置(如用户自定义设置、主题等)
    • 浏览器行为跟踪(如跟踪分析用户行为等

HTTPS

16

在上述介绍 HTTP 中,了解到 HTTP 传递信息是以明文的形式发送内容,这并不安全。而 HTTPS 出现正是为了解决 HTTP 不安全的特性为了保证这些隐私数据能加密传输, 让 HTTP 运行安全的 SSL/TLS 协议上,即 HTTPS = HTTP + SSL/TLS,通过 SSL 证书来验证服务器的身份,并为浏览器和服务器之间的通信进行加密 SSL 协议位于 TCP/IP 协议与各种应用层协议之间,浏览器和服务器在使用 SSL 建立连接时需要选择一组恰当的加密算法来实现安全通信,为数据通讯提供安全支持。

14

  • 流程图如下所示:

15

  • 首先客户端通过 URL 访问服务器建立 SSL 连接。

  • 服务端收到客户端请求后,会将网站支持的证书信息(证书中包含公钥)传送一份给客户端。

  • 客户端的服务器开始协商 SSL 连接的安全等级,也就是信息加密的等级。

  • 客户端的浏览器根据双方同意的安全等级,建立会话密钥,然后利用网站的公钥将会话密钥加密,并传送给网站。

  • 服务器利用自己的私钥解密出会话密钥。

  • 服务器利用会话密钥加密与客户端之间的通信。

  • 区别

    • HTTPSHTTP 协议的安全版本, HTTP 协议的数据传输是明文的,是不安全的, HTTPS 使用了 SSL/TLS 协议进行了加密处理,相对更安全。
    • HTTPHTTPS 使用连接方式不同,默认端口也不一样, HTTP80HTTPS443
    • HTTPS 由于需要设计加密以及多次握手,性能方面不如 HTTP
    • HTTPS 需要 SSLSSL 证书需要钱,功能越强大的证书费用越高。