HTTP 使用指南

发布时间 2023-07-24 09:56:29作者: SRIGT

0x1 初识 HTTP 协议

  1. 网页加载流程

    graph LR A(user 输入网址)==>B(browser 进程) B==>C(处理输入信息) B-->D(页面加载完成) C==>E(浏览器内核) E==>F(发起请求) F==>I(Internet) I==>J(服务器) J==>I E-->G(读取响应) E-->H(渲染) F-->G I==>G G==>H H==>D

    HTTP 位于 OSI 模型和 TCP/IP 的应用层(Application)

  2. 什么是 HTTP

    1. 超文本传输协议:Hyper Text Transfer Protocol

    2. 作为应用层协议,基于传输层的 TCP

    3. 分为请求响应两种模式

      1. 请求

        POST /index.php HTTP/1.1
        HOST: www.example.com
        Content-Type: application/json
        Content-Length: 15
        
        {"msg": "hello,world"}
        
      2. 响应

        HTTP/1.1 200 OK
        Data: Sun, 1, Jan 2022 00:00:00
        server: Tengine
        content-type: text/html; charset=utf-8
        
        <!doctype html><html><...
        
    4. 具有简单可扩展的特点

    5. 是一种无状态的协议:每个请求孤立

0x2 协议分析

  1. 发展历程

    graph LR A(HTTP/0.9<br/>单行协议)-->B(HTTP/1.0<br/>构建可扩展性) B-->C(HTTP/1.1<br/>标准化协议) C-->D(HTTP/2<br/>更优异的表现) D-->E(HTTP/3<br/>草案)
  2. 报文分析

    1. 请求 Requests

      POST /index.php HTTP/1.1
      HOST: www.example.com
      Content-Type: application/json
      Content-Length: 15
      
      {"msg": "hello,world"}
      
    2. 响应 Responses

      HTTP/1.1 200 OK
      Data: Sun, 1, Jan 2022 00:00:00
      server: Tengine
      content-type: text/html; charset=utf-8
      
      <!doctype html><html><...
      

    HTTP/1.1 报文结构:

    graph LR A(start-line)-->B(HTTP headers) A-->E(请求: Method Path Version) A-->F(响应: Version StatusCode StatusMessage) B-->C(empty line) C-->D(body)
    • Method:请求方法

      Method 描述 特点
      GET 请求一个指定资源的表示形式 Safe、Idempotent
      POST 用于将实体提交到指定的资源
      PUT 用请求有效载荷替换目标资源的所有当前表示 Idempotent
      DELETE 删除指定的资源 Idempotent
      HEAD 请求一个与 GET 请求的响应相同的响应,但没有响应体 Safe、Idempotent
      CONNECT 建立一个到由目标资源标识的服务器的隧道
      OPTIONS 用于描述目标资源的通信选项 Safe、Idempotent
      TRACE 沿着到目标资源的路径执行一个消息环回测试
      PATCH 用于对资源应用部分的修改
      • Safe:安全,不会修改服务器的数据的方法
      • Idempotent:幂等,同样的请求被执行一次与连续多次的效果相同、服务器状态相同
    • Path:请求资源路径

    • Version:使用的 HTTP 版本

    • StatusCode:状态码

      • 1xx:已接收,正在处理
      • 2xx:成功(200:请求成功)
      • 3xx:重定向,完成请求需要进一步操作(302:临时跳转)
      • 4xx:客户端错误(404:资源不存在)
      • 5xx:服务器端错误(504:网关超时)
      • 详解
    • StatusMessage:状态信息

    • RESTful API:一种 API 设计风格(Representational State Transfer)

      • 每个 URI 代表一种资源
      • 客户端与服务器之间传递这种专业的某种表现层
      • 客户端通过 Method 对服务器端资源进行操作,实现表现层状态转化
    • 常用请求头

      请求头 描述
      Accept 接收类型,表示浏览器支持的 MIME 类型
      Content-Type 客户端发送出去实体内容的类型
      Cache-Control 指定请求和响应遵循的缓存机制
      If-Modified-Since 对应服务端的 Last-Modified,用来匹配看文件是否变动
      Expires 缓存,在这个时间内不会请求,直接使用缓存,服务端时间
      Max-age 代表资源在本地缓存多少秒,有效时间内不会请求,而是使用缓存
      If-None-Match 对应服务端的 ETag,用来匹配文件内容是否改变
      Cookie 有 cookie 并且同域访问时会自动带上
      Referer 该页面的来源 URL
      Origin 最初的请求发起的源头(端口)
      User-Agent 用户客户端的一些必要信息
    • 常用响应头

      响应头 描述
      Content-Type 服务端返回的实体内容的类型
      Cache-Control 指定请求和响应遵循的缓存机制
      Last-Modified 请求资源的最后修改时间
      Expires 应该在什么时候认为文档已经过期
      Max-age 客户端的本地资源应该缓存时间(开启 Cache-Control 后有效)
      ETag 资源的特定版本的标识符
      Set-Cookie 设置和页面关联的 Cookie,服务器通过这个头部把 Cookie 传给客户端
      Server 服务器的一些相关信息
      Access-Control-Allow-Origin 服务器端允许的请求 Origin 头部
    • 缓存:强缓存、协商缓存

      graph LR A(开始)-->B(浏览器) B-->C(发起 GET 请求) D(读取浏览器缓存)--将缓存返回浏览器-->C C-->E{是否有缓存} E--是-->F{强缓存是否新鲜} F--是-->D F--否-->G(上一次响应头是否有 ETag) G--是-->H(发起请求, 请求头带 If-None-Match) G--否-->I{上一次响应头是否有 Last-Modified} I-->J(发起请求, 请求头带 If-Modified-Since) H-->K{状态是否为 304} J-->K K--304-->D K--200-->L(请求响应完成) L-->M(协商缓存)
    • Cookie

      Set-Cookie-response 描述
      Name=value 各种 cookie 的名称和值
      Expires=Date 有效期,缺省时仅在浏览器关闭前有效
      Path=Path 限制指定 cookie 的发送范围的文件目录
      Domain=domain 限制 cookie 生效的域名
      secure 进制 HTTP 安全连接时才发送 cookie
      HttpOnly JS 脚本无法获得 cookie
      SameSite=[None|Strict|Lax] None:同站、跨站都可以发送
      Strict:仅在同站发送
      Lax:允许与顶级导航一起发送
  3. HTTP/2 概述

    1. 帧(frame):HTTP/2 通信的最小单位,每个帧都包含帧头,至少也会标识出当前帧所属的数据流
    2. 消息:与逻辑去或响应信息对应的完整的一系列帧
    3. 数据流:已建立的连接内的双向字节流,可以承载一条或多条信息
    4. 流控制:阻止发送方向接收方发送大量数据的机制
  4. HTTPS 概述

    1. Hyper Text Transfer Protocol Secure
    2. 通过 TSL/SSL 加密
      1. 对称加密:密钥相同
      2. 非对称加密:分公钥和私钥

0x3 场景分析

  1. 静态资源
    1. 静态资源方案:缓存 + CDN + 文件名Hash
      • CDN:Content Delivery Network
      • 通过用户就近性和服务器负载的判断,CDN 确保内容以一种极为高效的方式为用户的请求提供服务
  2. 登录
    1. 业务场景:表单填写/扫码
    2. 技术方式:SSO(单点登录:Single Sign On)
    3. 当出现跨域时,会出现 OPTIONS 请求
      • 域名构成:[Scheme]://[HostName]:[port]
    4. 操作流程
      1. 向目标域名的目标 path 使用 POST 方法发送请求
      2. 携带信息:
        • 发送的数据格式为 form(表单)
        • 希望获取的数据格式为 json
        • 已有的 cookie
      3. 返回信息
        • 数据格式为 json
        • 各种 cookie 的信息
      4. 鉴权
        • Session + cookie
        • JSON Web Token
  3. 跨域
    1. 跨域解决方案
      1. CORS:Cross-Origin Resource Sharing
      2. 代理服务器
      3. Iframe(不推荐)

0x4 实战分析

  1. 浏览器

    1. Ajax 的 XHR

      1. XHR:XML Http Request

      2. ready 说明
        UNSENT 代理被创建,但尚未调用open()方法
        OPENED open()方法已被调用
        HEADERS_RECEIVED send()方法已被调用,并且头部和状态已经可获得
        LOADING 下载中
        DONE 下载操作已完成
    2. Ajax 的 Fetch

      1. XHR 升级版
      2. 使用 Promise
      3. 模块化设计响应、请求和头部对象
      4. 通过数据流处理对象,支持分块读取
      postData('http://example.com/answer', { answer: 42 })
          .then(data => console.log(data))
          .catch(err => console.log(err))
      
      function postData(url, data) {
          return fetch(url, {
              body: JSON.stringify(data),
              cache: 'no-cache',
              credentials: 'same-origin',
              headers: {
                  'user-agent': 'Mozila/4.0 MDN Example',
                  'content-type': 'application/json'
              },
              method: 'POST',
              mode: 'cors',
              redirect: 'follow',
              referrer: 'no-referrer'
          }).then(res => res.json())
      }
      
  2. NodeJS

    1. 标准库 HTTP/HTTPS

      1. 默认模块,功能有限
    2. 常用请求库 axios

      // 全局配置
      axios.defaults.baseURL = "http://api.example.com";
      // 添加请求拦截器
      axios.interceptors.request.use(function(cfg) {
          // 在发送请求前的操作
          return cfg;
      }, function(err) {
          // 对错误请求的操作
          return Promise.reject(err);
      });
      
      // 发送请求
      axios({
          method: 'get',
          url: 'http://test.com',
          responseType: 'stream'
      }).then(function(res) {
          res.data.pipe(fs.createWriteStream('ada_lovelace.jpg'))
      });
      
  3. 用户体验

    1. 网络优化

      graph TB A(网络优化)-->B(HTTP/2) B-->B1(优势) B1-->B11(Binary Format) B1-->B12(Multiplexed) B1-->B13(Server Push) B1-->B14(Header Optimize) B-->B2(兼容性) B-->B3(简单实践) B-->B4(HTTP/3) A-->C(CDN 动态加速) C-->C1(适用场景) C-->C2(缓存) C2-->C21(回源策略) C2-->C22(缓存刷新) C2-->C23(缓存预热) C2-->C24(缓存击穿) C-->C3(实践) A-->D(DNS 预解析) A-->E(网络预连接) A-->F(域名) F-->F1(域名收敛) F-->F2(域名发散) A-->G(压缩) G-->G1(gzip) G-->G2(brotil) A-->H(HTTPS 性能优化)
    2. 稳定性

      graph TB A(稳定性)-->B(重试机制) B-->B1(超时) B-->B2(错误) A-->C(缓存) A-->D(数据安全) D-->D1(HTTPS) D-->D2(劫持)

0x5 扩展

  1. 通信方式-WebSocket
    • 浏览器与服务器进行全双工通讯的网络技术
    • 适用于对实时性要求较高的场景
    • URL 使用ws://wss://等开头
  2. QUIC
    • Quick UDP Internet Connection

首发于HTTP 使用指南 | 青训营笔记

-End-