一、什么是 HTTP 协议

Hypertext Transfer Protocol 超文本传输协议,是基于 TCP/IP 协议的应用层协议。默认端口号是 80.

二、特点

  1. 简单快捷
    当客户端向服务器发送请求时,只需传送请求方法和路径。
  2. 灵活
    HTTP 允许传输任意类型的数据对象,由 Content-Type 加以标记。
  3. 无连接
    每次连接只处理一个请求。服务器处理完客户端请求,并收到客户端应答后,立即断开连接。节省传输时间。
  4. 无状态
    不对请求和响应之间的状态进行保存。
  5. 支持 B/S 、 C/S 模式

三、组成

  • http 报文是一个格式化的数据块。
  • 所有报文分为请求报文和响应报文。
    • 请求报文格式 ```xml

  1. - 响应报文格式:
  2. ```xml
  3. <version> <status> <reason-phrase>
  4. <headers>
  5. <entity-body>
  • http 报文由三个部分组成:
    • 对报文进行描述的起始行 Start line
    • 包含属性的首部块 Header
    • 包含数据的主体部分 Body,可选

HTTP 协议 - 图1

1.起始行

请求行

请求报文的起始行。包含了一个方法、一个请求 URL和 http 版本号。字段间由空格分隔。

响应行

响应报文的起始行。包含响应报文使用的 http 版本号、响应状态码和描述状态的原因短语。

方法

HTTP1.0 包含 3 种请求方法:GET、POST、HEAD
HTTP1.1新增 5 种请求方法:OPTIONS、PUT、DELETE、TRACE、CONNECT

  • GET
    从指定的资源请求数据。一般 GET 方法只用于数据的读取。GET 是不安全的请求方法,因为请求 URL 可以被爬虫任意访问。
  • POST
    向指定资源提交数据进行处理请求。数据被包含在请求体中。POST 请求可能导致资源被修改或新资源建立。
  • HEAD
    与 GET 方法类似,向服务器发出指定资源请求。服务器响应 HEAD 请求时不会返回响应主体,只返回响应头信息,一般用于客户端查看服务端的性能。
  • OPTIONS
    与 HEAD 方法类似,一般也是用于客户端查看服务器的性能。返回服务器支持的 HTTP 方法。JavaScript 的 XMLHttpRequest 对象进行 CORS 跨域请求时,会使用 OPTIONS 方法先发送一个嗅探请求,用来判断是否对指定资源有访问权限。
  • PUT
    上传内容到指定资源位置。
  • DELETE
    请求服务器删除所请求 URI 所标识的资源。
  • TRACE
    回显服务器收到的请求,主要用于测试或诊断。
  • CONNECT
    HTTP1.1 预留方法,能够将连接改为管道方式的代理服务器。通常用于 SSL 加密服务器的链接与非加密的 HTTP 代理服务器的通信。

状态码

  • 100 ~ 199 信息性状态码

    • 100: Continue
      说明收到了请求的初始部分,请客户端继续。发送了这个状态码之后,服务器在收到请求之后必须进行响应。
    • 101: Switching Protocols
      说明服务器正在根据客户端的指定,将协议切换成 Update 首部所列的协议。
  • 200 ~ 299 成功状态码

    • 200 OK
      请求没问题,实体的主体部分包含了所请求的资源。
    • 201 Created
      用于创建服务器对象的请求,例如 PUT。
    • 202 Accepted
      请求已被接受,但服务器还未对其执行任何操作。
    • 203 Non-Authoritative Information
      实体首部包含的信息不是来自于源端服务器,而是来自资源的一份副本。
    • 204 No Content
      响应报文中包含若干首部和一个状态行,但没有实体的主体部分。例如表单刷新。
    • 205 Reset Content
      告知浏览器清楚当前页面中的所有 HTML 表单元素。
    • 206 Partial Content
      成功执行了一个部分或 Range 请求。
  • 300 ~ 399 重定向状态码

    • 300 Multiple Choices
      客户端请求一个实际指向多个资源的 URL。
    • 301 Moved Permanently
      在请求的 URL 已被移除时使用。响应的 Location 首部中应该包含资源现在所处的 URL。永久重定向
    • 302 Found
      临时重定向,客户端应该使用 Location 首部给出的 URL 来临时定位资源。将来的请求仍用老的 URL
    • 303 See Other
      告知客户端应该用另一个 URL 来获取资源。新的 URL 位于响应报文的 Location 首部。其主要目的是允许 POST 请求的响应将客户端定位到某个资源上去。
    • 304 Not Modified
      资源未被修改,使用缓存内容。
    • 305 Use Proxy
      说明必须通过一个代理来访问资源。
    • 307 Temporary Redirect
      临时重定向,与 302 的区别是 HTTP 版本的区别。
  • 400 ~ 499 客户端错误状态码

    • 400 Bad Request
      用于告知客户端它发送了一个错误的请求。
    • 401 Unauthorized
      认证失败,无访问权限。
    • 402 Payment Required
    • 403 Forbidden
      请求被拒绝。
    • 404 Not Found
      资源不存在。
    • 405 Method Not Allowed
      不支持所请求的方法。在响应首部的 Allow 中告知客户端可以使用哪些方法。
    • 406 Not Acceptable
    • 407 Proxy Authentication Required
    • 408 Request Timeout
    • 409 Conflict
    • 410 Gone
    • 411 Length Required
    • 412 Precondition Failed
    • 413 Request Entity Too Large
    • 414 Request URI Too Large
    • 415 Unsupported Media Type
    • 416 Requested Range Not Satisfiable
    • 417 Expectation Failed
  • 500 ~ 599 服务器错误状态码

    • 500 Internal Server Error
      服务器内部错误
    • 501 Not Implemented
      请求超出服务器的能力范围
    • 502 Bad Gateway
      无法连接
    • 503 Service Unavailable
      服务器暂时无法提供服务
    • 504 Gateway Timeout
      请求超时
    • 505 HTTP Version Not Supported

版本

HTTP/1.0

在 HTTP/0.9 只有 GET 的基础上,增加 POST 和 HEAD 方法,响应内容支持多媒体内容。
请求和响应都增加了版本号、头部信息,响应内容有状态码、引入字符集、授权认证、缓存、内容编码等。
1.0 的缺点是一个连接只能有一次请求,每次请求都要重新建立 TCP 连接,而 TCP 连接的建立需要三次握手,加上慢启动特性,对资源和性能都是一种消耗。

HTTP/1.1

默认情况下所有连接都被保持,即请求头标记了 Connection: keep-alive ,只有当有 Connection: close 标记时,才会被关闭。

  • 持久连接

    1. Connection: Keep-Alive
    2. Keep-Alive: max=5, timeout=120
  • 管道机制
    指在一个连接上,客户端发送请求时不需要等待服务端响应后才发送下一个请求,可以连续发几个请求,服务端按照接受请求的顺序依次把响应返回。在响应头部添加 Content-Length: 2333 字段,声明本次响应的数据长度(字节),则后面的字节属于下一个请求的响应。

  • 分块传输
    对于有些数据操作,服务端无法提前知道所返回数据的长度,因此无法使用 Content-Length ;为此采用一种分块传输的方式处理响应,即产生一块数据就发送一块数据。在响应头部加入 Transfer-Encoding: chunked 表明数据由未定的数据块组成。

1.1虽然可以是持久连接,并引入了管道机制,但其核心还是要按照顺序处理内容,返回响应内容。下一个响应必须等待上一个请求处理完毕,即 对头堵塞 head-of-line blocking
优化方法:减少请求;多开持续连接(域名分片)

HTTP/2

二进制协议、多路复用、头信息压缩、推送、请求优先级、安全。

2.首部

首部字段向请求和响应报文添加了一些附加信息。本质上它们是一些名/值对的列表。例如Content-Length: 19
首部分为:

  • 通用首部
    既可以出现在请求报文中,也可以出现在响应报文中。
    Date: ``Tue, 09 Oct 2018 15:32:08 GMT

  • 请求首部
    提供更多有关请求的信息。

Accept: text/html,image/apng,*/*

  • 响应首部
    提供更多有关响应的信息。
    Server: nginx

  • 实体首部
    描述主体的长度和内容,或者资源本身。
    Content-type: text/html; charset=utf-8

  • 扩展首部
    自定义扩展
    X-id: xxx

3.主体

实体主体部分是可选的。主体是 HTTP 报文的负荷,即 HTTP 要传输的内容。

四、GET 与 POST 的区别

  • GET

    查询字符串是在 GET 请求的 URL 中发送的: /path?name1=value1&name2=value2...


    • 用于获取资源
    • 请求可被缓存
    • 请求保留在浏览器历史记录中
    • 数据长度受 URL 长度限制,最大 2048 个字符
    • 幂等
  • POST

    查询字符串是在 POST 请求的 HTTP 消息主体中发送:

  1. POST URL HTTP/1.1
  2. Host: xxx.com
  3. name1=value1&name2=value2...

    • 用于提交数据
    • 请求不可缓存
    • 请求不会保留在浏览器历史记录中
    • 数据长度无限制
    • 不幂等

五、持久连接 Keep-Alive

HTTP/1.1 默认开启持久连接 Connection: keep-alive , 减少建立连接次数,提升性能。

六、Cookie

  • Cookie 是指网站为了辨别用户身份、进行 session 跟踪而存储在用户本地客户端的数据。
  • 每个 cookie 大小限制 4KB
  • cookie 由服务端在响应头部设置 Set-Cookie: name=value;path=/;...
  • 删除 cookie 是将过期时间 Expire 设为 0 或 负值,关闭浏览器时会被清除
  • 发送请求会自动带上 cookie 信息到服务器,过多 cookie 会增加流量
  • 创建 cookie 需要浏览器开启 cookie
  • 临时 cookie 在关闭浏览器后被清除,永久 cookie 通过设置过期时间实现
  • js 通过 document.cookie 操作

属性

  • expires 过期时间
    expires = new Date().toGMTString();
  • domain 域
    domain = xxx.com
  • path 路径
    path = /
  • secure
    标记,在 https 的请求中,包含该标记的 cookie 才会被发到服务器
  • HttpOnly
    标记 cookie 不能通过 document.cookie 获取

七、内容分发网络 CDN

内容分发网络就是对特定内容进行分发的专门网络。这个网络中的节点可以是 Web 服务器、反向代理或缓存。

八、 HTTPS

https 是在安全的传输层上发送的 http。https 没有将未加密的 http 报文发送给 TCP。它在发送给 TCP 之前,先将其发送给了一个安全层,对其进行加密。
http 安全层是通过 SSL 及其现代代替协议 TLS 来实现的。

九、缓存控制

Expires

在 HTTP/1.0 中,通过 Expires 设置服务端过期时间,在下一次请求时,如果时间小于服务端设置的这个过期时间,则直接使用当前缓存的数据。但该时间是服务端生成,与客户端时间可能不一致,会导致缓存命中的误差。需与 Last-Modified 结合使用
在 1.1 中,使用 Cache-Control 代替

Cache-Control

通用首部,用于通过指令指定缓存机制。值有:

  • private : 默认值,客户端可以缓存
  • public : 客户端和代理服务器都可以缓存
  • max-age: 3600 : 缓存内容将在 3600 秒后失效
  • no-cache : 需要使用对比缓存来验证缓存数据
  • no-store : 所有内容都不会被缓存

如果服务器同时设置了 expires 和 cache-control ,则 expires 无效。
对比缓存:判断是否可以使用缓存。当服务器返回 304 时,表示可以继续使用缓存数据。

Last-Modified/If-Modified-Since

当第一次请求一个资源时,服务器返回 200 OK,同时返回一个 Last-Modified 属性标记资源在服务器最后被修改的时间,例如
Last-Modified: Wed, 10 Oct 2018 06:45:14 GMT
再次请求该资源时,根据 HTTP 协议规定,客户端向服务器发送 If-Modified-Since 报头,询问在这个时间后资源是否有被修改。若无修改,则服务器返回 304 Not Modified,客户端使用缓存资源。

ETag/If-None-Match

ETag: 被请求变量的实体标记。即服务器响应时给请求的 URL 标记