Willson Chen

Stay Hungry, Stay Foolish.

HTTP 协议

HTTP 协议

  • HTTP(Hyper Text Transfer Protocol)超文本传输协议。

特点

  • 基于 TCP 协议,默认端口 80。
  • 基于请求响应模型。
  • 无状态

版本历史

  • 1.0,默认短连接,请求队列阻塞。
  • 1.1,默认长连接,请求应答管线化不阻塞,增强缓存控制等。
  • 2.0,在TCP上增加二进制分桢层,支持多路复用及优先级,头部压缩,服务器推送等。
  • 高版本兼容低版本。

请求报文格式

  • 请求行,起始行包括【请求方法 URI 版本号】。
    • 请求方法,如GET/POST/HEAD/PUT/DELETE等。
    • URI,请求的资源路径。
    • 版本号,如HTTP/1.1。
  • 请求头,键值对
    • 字段名不区分大小写,可用符号-,不可用下划线。
    • 字段名后紧跟冒号,字段值前可以多个空格。
    • 不区分顺序。
  • 空行,CRLF 换行符,\r\n
  • 请求体,POST 请求的请求体。

响应报文格式

  • 状态行,包括【版本号 状态码 状态描述】。
    • 版本号,如HTTP/1.1。
    • 状态码,三位数,如 200/404/500等。
  • 响应头,键值对。
  • 空行,CRLF 换行。
  • 响应体,服务器响应的资源。

请求方法

  • GET,获取信息,参数附在 URL 后,存在长度限制。
  • POST,提交信息,数据在请求体中。
  • HEAD,只请求头部。
  • PUT,创建资源。
  • DELETE,删除资源。
  • PATCH,修改资源。
  • OPTIONS,查询指定 URL 支持的 HTTP 方法。

请求头字段

  • Host:服务器的域名或 IP 地址,如默认 80 端口可省略。
  • Connection:keep-alive表示保持连接,close 为关闭连接。
  • Accept:接受的内容各类型,如application/json。
  • Accept-Encoding:接受的编码格式,如gzip。
  • Accept-Language:接受的语言,如 zh-CN。
  • Referer:前一个页面地址。
  • Cache-Control:缓存控制,如no-cache不使用缓存。
  • User-Agent:发起请求的用户代理,如浏览器或客户端软件。
  • Cookie:发送给服务端的Cookie。

状态码

  • 1XX,信息类,需继续请求。
  • 2XX,成功类,200为 OK。
  • 3XX,重定向类,301为永久重定向,302为临时重定向
    • 304 未修改,客户端可以使用之前的缓存。
  • 4XX,客户端错误,404为找不到资源。
  • 5XX,服务器错误,500为服务器内部错误。

响应头字段

  • Age:在缓存代理服务中驻留的时长,单位秒。
  • Content-Length:内容长度,只有持久连接时才有效。
  • Content-Type:内容类型,如text/html。
  • Set-Cookie:设置 Cookie
  • Expires
    • 由HTTP1.0支持。
    • 在响应头中返回 Expires,客户端根据该时间判断是否重新请求。
    • 存在问题,服务器时间与客户端时间可能不一致。
  • Cache-Control
    • 由HTTP1.1支持,优先级高于 Expires。
    • 逗号分隔值
    • 值 no-store,不使用缓存
    • 值 no-cache,未与服务端验证新鲜度前不允许返回客户端使用。
    • 值 public 公有,可被中间层缓存。
    • 值 private 私有,不可被中间层缓存。
    • 值 max-age=秒,替代 Expire。
  • Last-Modified
    • 值为UTC时间,到秒。
    • 表示资源最后修改时间,用于客户端判断缓存是否最新。
    • 下次请求时头部会包含 If-Modified-Since。
  • Etag
    • 值为一个标识,资源发送修改会生成新的。
    • 比Last-Modified(到秒)更准确。
    • 下次请求时头部会包含 If-None-Match。

长连接、管线化和多路复用

  • 长连接
    • 长连接是指请求响应后不断开TCP连接。
    • HTTP/1.1起,如果客户端不设置Connection,默认表示Keep-Alive长连接。
    • 服务端如果支持长连接,则相应头Connection为Keep-Alive,开启长连接。
    • 如果没有再请求,通过超时机制断开连接,linux的tcp保活时间是2小时(t1 + t2 * N)
  • 管线化
    • 管线化是解决请求响应模型的阻塞问题,只针对get/head请求。
    • 多个请求管线化发起,服务端再按顺序管线化响应。
    • 管线化仍然存在队头阻塞问题,因为必须确保响应的有序性。
    • 浏览器通常会使用发起多个长连接的方式来缓解队头阻塞问题。
  • 多路复用
    • 多路复用是指在一个TCP连接上实现任意请求的并行传输。
    • HTTP/2.0起支持多路复用。
    • 底层是基于二进制分帧,每个请求有唯一流ID,分成多个帧传输,接收方组装得到。

URI

  • URI(Uniform Resource Identifier),统一资源标识符。
  • 用来唯一标识资源。
  • 格式:scheme://[user:password@]host[:port]/path[?query][#fragment]
    • scheme为协议,如http、https、ftp、ssh、smb等。
    • user:password@为登录的用户和密码,非必需。
    • host:port为主机名和端口,端口省略表示使用协议默认端口。
    • path为资源所在的位置。
    • query为查询参数,为key=val形式,多个用&隔开。
    • fragment表示资源内的锚点。
  • URI只能用ASCII码,非ASCII的字符和界定符需转为百分号编码(十六进制字节值,在前面加%号)。
  • URL用来定位资源,URI只是标识资源。