HTTP 使用指南 | 青训营笔记
这是我参与「第五届青训营」伴学笔记创作活动的第 5 天
0x1 初识 HTTP 协议
-
网页加载流程
HTTP 位于 OSI 模型和 TCP/IP 的应用层(Application)
-
什么是 HTTP
-
超文本传输协议:
Hyper Text Transfer Protocol
-
作为应用层协议,基于传输层的 TCP
-
分为请求和响应两种模式
-
请求
POST /index.php HTTP/1.1 HOST: www.example.com Content-Type: application/json Content-Length: 15 {"msg": "hello,world"}
-
响应
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><...
-
-
具有简单可扩展的特点
-
是一种无状态的协议:每个请求孤立
-
0x2 协议分析
-
发展历程
-
报文分析
-
请求 Requests
POST /index.php HTTP/1.1 HOST: www.example.com Content-Type: application/json Content-Length: 15 {"msg": "hello,world"}
-
响应 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 报文结构:
-
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 头部 -
缓存:强缓存、协商缓存
-
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:允许与顶级导航一起发送
-
-
HTTP/2 概述
- 帧(frame):HTTP/2 通信的最小单位,每个帧都包含帧头,至少也会标识出当前帧所属的数据流
- 消息:与逻辑去或响应信息对应的完整的一系列帧
- 数据流:已建立的连接内的双向字节流,可以承载一条或多条信息
- 流控制:阻止发送方向接收方发送大量数据的机制
-
HTTPS 概述
- Hyper Text Transfer Protocol Secure
- 通过 TSL/SSL 加密
- 对称加密:密钥相同
- 非对称加密:分公钥和私钥
0x3 场景分析
- 静态资源
- 静态资源方案:缓存 + CDN + 文件名Hash
- CDN:Content Delivery Network
- 通过用户就近性和服务器负载的判断,CDN 确保内容以一种极为高效的方式为用户的请求提供服务
- 静态资源方案:缓存 + CDN + 文件名Hash
- 登录
- 业务场景:表单填写/扫码
- 技术方式:SSO(单点登录:Single Sign On)
- 当出现跨域时,会出现 OPTIONS 请求
- 域名构成:
[Scheme]://[HostName]:[port]
- 域名构成:
- 操作流程
- 向目标域名的目标 path 使用 POST 方法发送请求
- 携带信息:
- 发送的数据格式为 form(表单)
- 希望获取的数据格式为 json
- 已有的 cookie
- 返回信息
- 数据格式为 json
- 各种 cookie 的信息
- 鉴权
- Session + cookie
- JSON Web Token
- 跨域
- 跨域解决方案
- CORS:Cross-Origin Resource Sharing
- 代理服务器
- Iframe(不推荐)
- 跨域解决方案
0x4 实战分析
-
浏览器
-
Ajax 的 XHR
-
XHR:XML Http Request
-
ready 说明 UNSENT 代理被创建,但尚未调用 open()
方法OPENED open()
方法已被调用HEADERS_RECEIVED send()
方法已被调用,并且头部和状态已经可获得LOADING 下载中 DONE 下载操作已完成
-
-
Ajax 的 Fetch
- XHR 升级版
- 使用 Promise
- 模块化设计响应、请求和头部对象
- 通过数据流处理对象,支持分块读取
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()) }
-
-
NodeJS
-
标准库 HTTP/HTTPS
- 默认模块,功能有限
-
常用请求库 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')) });
-
-
用户体验
-
网络优化
-
稳定性
-
0x5 扩展
- 通信方式-WebSocket
- 浏览器与服务器进行全双工通讯的网络技术
- 适用于对实时性要求较高的场景
- URL 使用
ws://
或wss://
等开头
- QUIC
- Quick UDP Internet Connection