HTTP 与 HTTPS 完全指南

34 阅读50分钟

一、网络分层与协议位置

1.1 七层、五层、四层模型对照表

三种模型在同一张表中对照(自下而上:第 1~7 行对应物理层到应用层)。

  • 口诀:物数网传会表应(从下往上记)。
  • 层组列:标出各层归属。
  • 表中「↑ 同上」:与上一格属同一层(无独立层界)。
层组OSI 七层TCP/IP 五层TCP/IP 四层对应关系主要功能典型协议 / 例子典型设备
应用层第 7 层 应用层第 5 层 应用层第 4 层 应用层7、6、5 → 应用层;HTTP/HTTPS 在此层(端口 80/443,基于 TCP)为应用程序提供网络服务接口HTTP、HTTPS、FTP、SMTP、DNS、WebSocket主机、终端、应用网关
应用层第 6 层 表示层↑ 同上↑ 同上↑ 同上数据格式转换、加解密、压缩SSL/TLS(部分)、JPEG、MPEG、编码↑ 同上
应用层第 5 层 会话层↑ 同上↑ 同上↑ 同上建立、管理、终止会话RPC、NetBIOS、SQL 会话↑ 同上
传输层第 4 层 传输层第 4 层 传输层第 3 层 传输层4 → 传输层端到端可靠/不可靠传输、端口寻址TCP、UDP主机(端设备)
网络层第 3 层 网络层第 3 层 网络层第 2 层 网际层3 → 网络层/网际层路由选择、逻辑寻址、分组转发IP、ICMP、ARP路由器
数据链路层第 2 层 数据链路层第 2 层 数据链路层第 1 层 网络接口层2 → 数据链路层;四层中 2、1 → 网络接口层成帧、差错控制、MAC 寻址Ethernet、WiFi、PPP交换机、网桥
物理层第 1 层 物理层第 1 层 物理层↑ 同上1 → 物理层;四层中 ↑ 同上比特流传输、物理接口与介质双绞线、光纤、无线电中继器、集线器、网卡

SSL/TLS 属于哪一层(常考)

  • OSI 七层:通常归表示层(第 6 层)(加解密、数据格式转换);也有归会话层(第 5 层)(建立与管理安全会话)的说法。
  • TCP/IP 四层/五层:无单独表示层、会话层,故归入应用层
  • 通俗记:SSL/TLS 夹在应用协议(如 HTTP)与传输层(TCP)之间——对应用层是「下面一层」的加密通道,对 TCP 是「上面一层」的 payload。

二、HTTP 概述

2.1 定义与全称

  • 全称:HyperText Transfer Protocol(超文本传输协议)。
  • 定义:HTTP 是应用层协议,在浏览器与服务器之间传输数据,基于 TCP(默认端口 80,HTTPS 为 443),采用请求-响应模式:客户端发请求,服务器回响应。
  • 为什么用 TCP 不用 UDP(常考):HTTP 需要可靠、有序地传输完整报文(请求/响应不能丢、不能乱序);TCP 提供可靠传输、流量控制、连接管理,适合这种语义。UDP 不保证可靠与有序,适合实时、可丢的场景(如音视频),不适合 HTTP 正文。

2.2 主要特点

特点说明
无状态(Stateless)每次请求独立,服务器不记录上次请求、不区分是否同一客户端。优点:实现简单、易水平扩展、易做负载均衡、单次失败不影响其他请求。缺点:登录态、购物车等需在应用层维护,常用 Cookie、Session 或 Token。
请求-响应(Request-Response)通信由客户端主动发起,一次请求对应一次响应,顺序固定。服务器不能主动向客户端推数据;若要实时推送需 WebSocket、SSE 等。
基于 TCP运行在 TCP 之上,保证数据可靠、有序到达;默认端口 80(HTTPS 为 443)。
明文传输默认不加密,请求与响应内容可被窃听、篡改。生产环境应使用 HTTPS(在 HTTP 与 TCP 之间增加 SSL/TLS 加密)。
灵活 / 可扩展支持多种请求方法(GET、POST、PUT、DELETE 等)、多种 Content-Type(JSON、表单、二进制等)和自定义头;协议本身可随版本(如 1.1、2、3)扩展而不破坏语义。

无状态补充:服务器不保存会话,同一用户多次请求在协议层面无关联。需要「记住用户」时,由应用自行实现,例如:

  • Cookie(存客户端)
  • Session(存服务端,用 SessionID 关联)
  • Token(如 JWT)

2.3 请求与响应的结构

  • 请求:请求行(方法 + URL + 协议版本)+ 请求头 + 空行 + 可选请求体。
  • 响应:状态行(协议版本 + 状态码 + 描述)+ 响应头 + 空行 + 可选响应体。

示例(请求):

GET /index.html HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0
Accept: text/html

示例(响应):

HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 1234

<html>...</html>

2.4 版本演进与特性对照

各版本主要特性对照(— 表示无或不适用)。

特性HTTP/0.9HTTP/1.0HTTP/1.1HTTP/2HTTP/3
连接短连接默认短连接默认长连接(Keep-Alive)长连接 + 多路复用基于 QUIC,建连更快
Host 头不要求必须必须必须
请求头/响应头有(可压缩)
分块传输不支持支持(Chunked)支持支持
缓存多用 Expires多用 Cache-Control同 1.1同 1.1
范围请求不支持支持(Range / 206)支持支持
多路复用不支持(有队头阻塞)支持支持
头部压缩HPACKQUIC 内建
二进制分帧文本文本二进制帧二进制
服务端推送不支持支持支持
传输层TCPTCPTCPTCPQUIC(UDP)
备注仅 GET,已废弃引入状态码、Content-Type当前最常用多需 HTTPS减少队头阻塞

2.5 多路复用、头部压缩、二进制分帧、服务端推送(HTTP/2)

下表对版本表中出现的四项 HTTP/2 特性做简要说明。

概念含义与作用
多路复用(Multiplexing)同一条 TCP 连接上同时收发多组请求/响应,互不阻塞。HTTP/1.1 下同连接请求串行,易队头阻塞;多路复用后请求可交错、响应可乱序,提高带宽利用、降低延迟。
头部压缩(Header Compression)请求/响应头重复多(如 Host、Cookie)。HTTP/2 用 HPACK 在连接上维护头表,只传差异或索引,减少重复,降低开销。
二进制分帧(Binary Framing)HTTP/1.x 为文本;HTTP/2 将报文拆成二进制帧(含类型、流 ID 等),便于解析、与多路复用配合(按流 ID 区分请求/响应)及做流控。
服务端推送(Server Push)服务器可在未收到请求时主动推送可能用到的资源(如 CSS、JS),减少 RTT,加快首屏;客户端可拒绝或取消。

三、HTTP 请求方法

3.1 常用方法对照

从用途、幂等性、安全性、参数位置、是否可缓存、典型场景等多方面对照。幂等:多次相同请求效果一致;安全:不改变服务器状态。

方法用途幂等安全参数/数据位置可缓存典型场景与备注
GET获取资源URL 查询串(?k=v&…),有长度限制,敏感信息不宜放 URL查询、获取页面/接口数据、下载;只读,不应改服务端状态
POST提交/创建请求体(表单、JSON、二进制等),长度通常不限提交表单、创建资源、登录、文件上传;多次相同请求可能产生多条数据
PUT全量更新请求体;URL 指向具体资源(如 /users/123)全量替换该资源;资源不存在时可约定为创建;幂等
DELETE删除一般无 body;URL 指向要删除的资源删除 URL 指定资源;常用 204 No Content;重复删除同一资源仍为幂等
HEAD只取头同 GET,无请求体与 GET 相同但只返回响应头;用于检查资源存在、大小、Last-Modified/ETag,省带宽
OPTIONS询问能力通常无 body返回 Allow 等;常用于 CORS 预检(Access-Control-*);不修改资源
PATCH部分更新通常否请求体(仅含要改的字段);URL 指向具体资源只更新部分字段,不替换整份资源;是否幂等取决于服务端实现

GET 与 POST 对比小结

  • GET:参数在 URL、可缓存、幂等且安全,适合查询。
  • POST:数据在 body、不缓存、非幂等,适合提交与创建。
  • 敏感数据、大数据量宜用 POST。

四、HTTP 状态码

4.1 分类概览

状态码首位数字表示类别,后两位表示具体含义。响应头与 body 由协议与实现决定,下表仅作语义说明。

类别范围含义
1xx100–199信息性:请求已接收,继续处理
2xx200–299成功:请求已被成功处理
3xx300–399重定向:需进一步操作(换 URL 或使用缓存)
4xx400–499客户端错误:请求有误或无法满足
5xx500–599服务端错误:服务器处理请求时出错

4.2 1xx 信息类

状态码含义用途特点
100 Continue请继续发送请求体客户端在发送较大 body 前先发头并带 Expect: 100-continue,服务器同意则先回 100,客户端再发 body避免大 body 被拒绝后白传,节省带宽
101 Switching Protocols同意切换协议升级到 WebSocket、HTTP/2 等时,服务器返回 101 并切换连接从 HTTP 升级为其他协议,后续同连接用新协议

4.3 2xx 成功类

状态码含义用途特点
200 OK请求成功最通用:GET 取到资源、POST 处理成功、PUT/PATCH 更新成功等,且返回有 body有响应体;若无需返回内容可用 204
201 Created资源已创建POST 创建新资源(如新用户、新订单)后返回通常带 Location 头指向新资源 URL;可选在 body 中返回资源表述
204 No Content成功但无返回内容请求成功且服务器不返回 body,如 DELETE 成功、PUT 更新后无需回传无响应体;客户端不应依赖 body 内容
206 Partial Content部分内容支持范围请求时,返回请求范围内的那一段(如断点续传、分片下载)需配合 Range 请求头;响应头常带 Content-Range 说明区间与总长

4.4 3xx 重定向类

状态码含义用途特点
301 Moved Permanently永久重定向资源长期迁到新 URL(如域名更换、目录永久调整)Location 指明新 URL;浏览器/代理可缓存;搜索引擎会把权重转到新 URL
302 Found临时重定向资源临时从别处提供(如临时维护页、A/B 跳转、登录后跳回)Location 指明临时 URL;不要求更新书签或缓存;SEO 不转移权重
303 See Other见其他位置POST 提交后引导用 GET 访问新 URL(如创建成功跳转到详情页)明确要求用 GET 访问 Location;与 302 区别在于语义上「用 GET 取新资源」
304 Not Modified未修改,用缓存协商缓存:客户端带 If-None-MatchIf-Modified-Since,服务器判断资源未变则回 304无响应体,客户端用本地缓存;节省带宽,常用于静态资源与接口缓存

301 与 302 考点小结

  • 301:永久重定向;浏览器/搜索引擎可更新为长期使用新 URL。
  • 302:临时重定向;不要求更新书签,SEO 不转移权重。
  • 选型:换域名、目录永久迁移用 301;登录后跳回、A/B 跳转用 302。

补充307(临时)、308(永久)与 302、301 类似,但规定重定向后不改变原请求方法(POST 仍用 POST);302/301 早期部分浏览器会把 POST 改成 GET,需严格保留方法时用 307/308。


4.5 4xx 客户端错误类

状态码含义用途特点
400 Bad Request错误请求请求语法、格式或参数有误(如 JSON 非法、必填项缺失、类型错误)客户端应修正请求再重试;可在 body 中返回具体错误信息
401 Unauthorized未认证需要登录或 Token,但未提供或已失效常带 WWW-Authenticate 说明认证方式;客户端应引导登录或刷新 Token
403 Forbidden禁止访问身份已识别,但无权限访问该资源(如权限不足、IP 被封、资源禁止访问)与 401 区别:401 是「未登录」,403 是「已登录但没权限」
404 Not Found未找到请求的 URL 对应资源不存在或对当前用户不可见最常见错误码之一;也可用于「存在但不想暴露」时统一返回 404
405 Method Not Allowed方法不允许该 URL 不支持当前请求方法(如对只读接口发 POST)响应头 Allow 列出允许的方法(如 Allow: GET, HEAD
429 Too Many Requests请求过多触发限流:同一客户端或同一 key 在时间窗口内请求次数超限常带 Retry-After 建议多久后重试;客户端应降频或排队重试

4.6 5xx 服务端错误类

状态码含义用途特点
500 Internal Server Error服务器内部错误服务端处理请求时发生未捕获异常、配置错误或依赖失败客户端无法通过改请求修复,可稍后重试;不应把业务校验错误当 500
502 Bad Gateway网关错误作为代理/网关时,从上游(如应用服务器)收到无效或错误响应常见于 Nginx 反向代理后端挂掉或返回非 HTTP;需检查上游服务与网络
503 Service Unavailable服务不可用服务暂时过载、维护或不可用,请稍后再试可带 Retry-After;与 502 区别:502 是「上游坏了」,503 是「本机过载或主动不可用」
504 Gateway Timeout网关超时作为代理/网关时,等待上游响应超时上游处理过慢或网络问题;客户端可稍后重试

502 / 503 / 504 考点小结

状态码含义
502网关从上游收到无效或错误响应(上游挂了、返回非 HTTP)
503本服务主动表示暂时不可用(过载、维护)
504网关等上游响应超时(上游太慢或网络问题)

:502 上游坏了/乱回,503 本机过载或维护,504 等上游响应超时。


五、HTTP 头部(常用)

头部用于传递请求/响应的元信息:内容类型、长度、缓存、认证等。键不区分大小写,建议按规范首字母大写。

5.1 请求头

请求头含义取值示例用途与注意
Host目标主机与端口Host: api.example.comHost: example.com:8080HTTP/1.1 必须;虚拟主机靠此区分;缺省端口可省略
User-Agent客户端标识User-Agent: Mozilla/5.0 (Windows NT 10.0; rv:91.0) Gecko/20100101 Firefox/91.0服务端做兼容、统计、限流;可伪造,勿用于安全判断
Accept希望接收的媒体类型Accept: application/jsonAccept: text/html, application/xml;q=0.9内容协商;q 表示优先级;服务端可选 406 表示无法满足
Accept-Language希望接收的语言Accept-Language: zh-CN, zh;q=0.9, en;q=0.8多语言站点或接口返回对应语言版本
Accept-Encoding希望接收的编码(压缩)Accept-Encoding: gzip, deflate, br服务端可对 body 压缩(如 gzip);响应头用 Content-Encoding 说明实际编码
Content-Type请求体的媒体类型Content-Type: application/jsonapplication/x-www-form-urlencodedmultipart/form-data; boundary=----xxx有 body 时建议显式设置;表单上传用 multipart
Content-Length请求体字节长度Content-Length: 1024有 body 时应正确设置;分块传输时不用此头
Cookie携带已存储的 CookieCookie: sessionid=abc; theme=dark由浏览器或客户端按域名/路径自动携带;由服务端通过 Set-Cookie 响应头下发并写入
Authorization认证信息Authorization: Bearer <token>Authorization: Basic <base64(user:pass)>常见:Bearer(JWT)、Basic(base64 编码的 用户名:密码);401 时可用 WWW-Authenticate 指明方式
Connection连接控制Connection: keep-aliveConnection: closeHTTP/1.1 默认 keep-alive;设为 close 表示本请求后关闭连接
Referer当前请求的来源页 URLReferer: https://www.example.com/page统计、防盗链、CSRF 校验;HTTPS→HTTP 时浏览器常不发送;可用 Referrer-Policy 控制
Origin请求来源域(不含路径)Origin: https://www.example.com跨域请求(如 CORS)时携带;服务端据此返回 Access-Control-Allow-Origin
If-None-Match协商缓存:资源 ETagIf-None-Match: "abc123"与响应 ETag 对比;未变则 304,变则 200 + 新内容
If-Modified-Since协商缓存:资源修改时间If-Modified-Since: Wed, 21 Oct 2024 10:00:00 GMT与响应 Last-Modified 对比;未变则 304
Range范围请求Range: bytes=0-1023只请求资源的一部分;服务端支持则回 206 Partial ContentContent-Range,用于断点续传、分片下载

5.2 响应头

响应头含义取值示例用途与注意
Content-Type响应体的媒体类型与编码Content-Type: text/html; charset=utf-8Content-Type: application/json客户端据此解析 body;可带 charset
Content-Length响应体字节长度Content-Length: 2048非分块响应时常用;客户端可据此做进度或校验
Content-Encoding响应体使用的编码(压缩)Content-Encoding: gzip表示 body 已压缩,客户端需先解压再按 Content-Type 解析
Cache-Control缓存策略Cache-Control: public, max-age=3600no-cacheno-store控制是否缓存、缓存时长、是否必须再验证;优先于 Expires
Expires缓存过期时间(绝对时间)Expires: Thu, 01 Dec 2024 12:00:00 GMT旧式缓存;与 Cache-Control 同时存在时以 Cache-Control 为准
Last-Modified资源最后修改时间Last-Modified: Wed, 21 Oct 2024 10:00:00 GMT协商缓存;客户端下次带 If-Modified-Since 比较,未变可 304
ETag资源版本标识ETag: "abc123"ETag: W/"weak123"协商缓存;客户端下次带 If-None-Match 比较;比 Last-Modified 更细
Set-Cookie下发 CookieSet-Cookie: sid=xxx; Path=/; HttpOnly; Secure; SameSite=Strict可多次出现;常用属性:PathDomainMax-Age/ExpiresHttpOnly(禁止 JS 读)、Secure(仅 HTTPS)、SameSite(防 CSRF)
Location重定向或新资源 URLLocation: https://example.com/newLocation: /api/users/1233xx 重定向时必填;201 时指向新创建资源(可相对或绝对)
Server服务器软件信息Server: nginx/1.18.0生产环境常隐藏或写通用名,避免暴露版本
Date响应生成时间Date: Wed, 21 Oct 2024 10:00:00 GMT建议 GMT;用于缓存计算、日志与调试
Access-Control-Allow-Origin允许的跨域来源Access-Control-Allow-Origin: https://www.example.com*CORS:允许哪些源可读本响应;预检还会用到 Access-Control-Allow-MethodsAccess-Control-Allow-Headers
Vary内容协商与缓存Vary: Accept-Encoding, User-Agent告诉缓存:仅当这些请求头的值与缓存时一致时才可用该缓存;否则需重新向服务器请求

5.3 CORS 与预检请求(常考)

同源与跨域

  • 同源 = 协议、域名、端口三者一致;跨域 = 任一项不同。
  • 浏览器同源策略下,前端脚本请求跨域地址时,默认会限制读取响应(如 XHR/fetch 报错)。
  • CORS(跨域资源共享):服务端返回 Access-Control-Allow-Origin 等头,告诉浏览器「允许该来源读取本响应」。
类型条件(满足即为简单请求)是否发预检
简单请求方法为 GET / HEAD / POST 之一;头仅含 Accept、Accept-Language、Content-Language、Content-Type(且 Content-Type 仅为 application/x-www-form-urlencodedmultipart/form-datatext/plain)等简单头不发 OPTIONS,直接发本次请求;服务器回 Access-Control-Allow-Origin 等即可
预检请求用了 PUT/DELETE/PATCH、或带了自定义头(如 Authorization、X-Requested-With)、或 Content-Type 为 application/json浏览器会先发 OPTIONS 请求(预检),询问服务器是否允许该方法、该头;服务器回 204 且带 Access-Control-Allow-MethodsAccess-Control-Allow-HeadersAccess-Control-Allow-Origin 等;通过后再发真正的 GET/POST/…

考点小结

  • 跨域时浏览器先判断是否为简单请求;非简单请求会先发 OPTIONS 预检,通过后再发实际请求。
  • 服务端需对 OPTIONS 返回允许的方法与头,并带 Access-Control-Allow-Origin;若带 Cookie 则需 Access-Control-Allow-Credentials: true 且不能为 *

CORS 预检流程示意

flowchart LR
    A[跨域请求] --> B{简单请求?}
    B -->|是| C[直接发 GET/POST 等]
    B -->|否| D[先发 OPTIONS 预检]
    D --> E{Allow-Origin 等?}
    E -->|通过| F[再发实际请求]
    E -->|不通过| G[跨域失败]
    C --> H[回 Access-Control-Allow-Origin]

六、HTTP 缓存

HTTP 缓存:浏览器(或代理)把某次请求得到的响应存起来,下次要同一资源时直接用这份副本,减少请求、省带宽、加快加载。

下次要同一资源时,浏览器怎么决定? 两种决策方式(不是两种「存法」):

  • 强缓存:在有效期内不发请求,直接用本地副本。
  • 协商缓存过期后(或要求每次验证时)发请求,带「上次的版本信息」;服务器判断是否变化 → 未变回 304 用本地,已变回 200 和新内容。

小结:强缓存 = 有效期内直接用;协商缓存 = 先问服务器,再根据 304/200 决定用本地还是新内容。

缓存决策流程示意

flowchart LR
    A[请求资源] --> B{有本地缓存?}
    B -->|否| C[请求服务器 200 存缓存]
    B -->|是| D{强缓存有效?}
    D -->|是| E[不发请求 用本地 cache]
    D -->|否| F[带 If-None-Match 等请求]
    F --> G{资源变化?}
    G -->|未变| H[304 用本地缓存]
    G -->|已变| I[200 更新缓存]

6.1 强缓存与协商缓存对照

类型是否发请求谁决定「用不用本地副本」典型状态码由哪些响应头控制
强缓存不发请求浏览器自己(看本地是否在有效期内)无(不产生 HTTP 请求)Cache-Control: max-age=…Expires
协商缓存发请求,带条件头服务器(根据条件头判断是否未修改)304(用本地)或 200(新内容)Last-ModifiedETag(请求时对应 If-Modified-SinceIf-None-Match
  • 强缓存:响应里带了 max-age 或未过期的 Expires 时,在有效期内浏览器不会向服务器发请求,直接用本地副本;过期后才会发请求,此时可能走协商缓存(304/200)或直接拿到新的 200。
  • 协商缓存:缓存过期或响应要求「每次都要验证」(如 no-cache)时,浏览器会发请求,并带上上次保存的 If-Modified-SinceIf-None-Match;服务器比较后若资源未变则返回 304(不返 body),浏览器用本地缓存;若已变则返回 200 和新内容。

6.2 缓存流程简述

  1. 首次请求(无本地缓存):请求服务器 → 200 + 响应头(Cache-Control、ETag/Last-Modified 等)→ 浏览器存下响应与这些头。
  2. 再次请求(未过期):若强缓存有效(如 max-age 未到期)→ 不发请求,直接用本地。
  3. 再次请求(已过期或 no-cache):发请求并带 If-None-Match(优先)或 If-Modified-Since → 服务器比较:
    • 未修改 → 返回 304(无 body),浏览器用本地缓存;
    • 已修改 → 返回 200 + 新 body,浏览器更新本地缓存。

304 之后会一直协商吗?

不一定。304 响应里可以带新的响应头(如 Cache-Control: max-age=3600Expires 等),浏览器会更新到该资源的缓存元数据。

  • 304 里带了新的 max-age 或未过期的 Expires:新有效期内再次访问 → 走强缓存(不发请求);新有效期过了再走协商缓存。
  • 304 里没给新有效期(或给了 no-cache:下次访问 → 再次发条件请求,继续走协商缓存。

结论:是否「每次都要协商」取决于 304 里是否设置了新的过期时间。

6.3 Cache-Control 常用指令

响应头中的 Cache-Control(可组合,多个指令用逗号分隔):

指令含义说明
no-store不缓存不存到磁盘/内存,每次都要从服务器取;最严格,敏感数据用
no-cache可存但每次都要验证会缓存,但再用前必须带条件头向服务器验证;未变则 304,变则 200
max-age=秒强缓存时长在此秒数内不发请求,直接用本地;如 max-age=3600 表示 1 小时内强缓存
s-maxage=秒共享缓存(如 CDN)的最大年龄仅对 public 的共享缓存生效,覆盖 max-age
private仅浏览器可缓存中间代理(CDN、反向代理)不应缓存,只允许最终用户浏览器缓存
public允许中间节点缓存浏览器和代理/CDN 都可以缓存
must-revalidate过期后必须再验证过期后不能直接用旧缓存,必须向服务器验证(可 304)

请求头中的 Cache-Control:如 no-cache 表示「我希望拿到最新内容」,可强制走协商(仍可能 304)。

6.4 Last-Modified 与 ETag

两者都用于协商缓存:服务器在响应里给出「资源版本」,下次请求时客户端带上对应条件头,服务器据此返回 304 或 200。

机制响应头请求条件头特点
Last-ModifiedLast-Modified: <GMT 时间>If-Modified-Since: <同上>精度到秒;1 秒内多次修改难区分;某些场景下可能被故意不改时间只改内容
ETagETag: "abc123"W/"weak"If-None-Match: "abc123"资源版本标识(如哈希),更精确;若同时存在,优先用 ETag(If-None-Match),因更可靠
  • ETag 强弱:强 ETag("xxx")要求字节完全一致;弱 ETag(W/"xxx")表示语义等价即可。
  • 优先级:若响应同时有 Last-ModifiedETag,规范建议以 ETag 为准(请求带 If-None-Match),避免时间精度与时钟问题。

6.5 小结

  • 缓存命中顺序(常考)
    • 先看强缓存是否有效(max-age 未过期、Expires 未到)→ 有效则不发请求直接用本地(memory cache / disk cache,通常先内存后磁盘)。
    • 无效或 no-cache 时再发请求走协商缓存(带 If-None-Match / If-Modified-Since)→ 服务器回 304 用本地或 200 更新。
  • 强缓存:看 Cache-Control(max-age)、Expires;有效期内不发请求。
  • 协商缓存:看 ETag / Last-Modified,请求带 If-None-Match / If-Modified-Since;服务器决定 304 或 200。
  • 304 之后:304 里若带新的 Cache-Control / Expires,浏览器会更新本地过期时间,新有效期内再走强缓存;若没带,下次仍发条件请求走协商缓存。
  • 优先级:Cache-Control 优先于 Expires;ETag 优先于 Last-Modified(两者同时存在时)。

七、连接管理

  • 背景:HTTP 基于 TCP,每次发请求前都要先建立 TCP 连接。
  • 连接管理要解决的问题:是「一个请求用一条连接、用完就关」,还是「一条连接复用、连续发多个请求」?
    • 短连接:一个请求用一条连接,用完就关。
    • 长连接(Keep-Alive):一条连接复用,连续发多个请求、收多个响应。
    • 管道化:在长连接上「连续发多个请求、不等响应就发下一个」;属 HTTP/1.1,与长连接并存(先有长连接才能管道化)。HTTP/1.x 下易队头阻塞,实际少用;HTTP/2 用多路复用从协议层解决。

连接方式对比示意

flowchart LR
    A1[建连] --> A2[请求1 响应1]
    A2 --> A3[关连]
    A3 --> A4[再建连]
    A4 --> A5[请求2 响应2]
    B1[建连] --> B2[请求1]
    B2 --> B3[响应1]
    B3 --> B4[请求2]
    B4 --> B5[响应2]
    C1[建连] --> C2[请求1+2+3]
    C2 --> C3[响应1+2+3 按序]

7.1 短连接

项目说明
做法每次 HTTP 请求都新建一条 TCP 连接,请求完成后立即关闭该连接;下次请求再重新建连。
典型版本HTTP/1.0 默认如此(当时未标准化 Keep-Alive)。
优点实现简单;服务器无需维护连接状态,适合无状态、请求量不大的场景。
缺点每次请求都要经历 TCP 三次握手、四次挥手,延迟与开销大;高并发时建连数多,占用端口与资源。

7.2 长连接(Keep-Alive)

项目说明
做法复用同一条 TCP 连接,在其上连续发送多个 HTTP 请求、接收多个响应;连接在一段时间内保持打开,由客户端或服务器在合适时机关闭(或由超时、最大请求数等策略关闭)。
典型版本HTTP/1.1 默认使用长连接(即默认 Connection: keep-alive);若不想复用,需显式发 Connection: close
如何声明请求头 Connection: keep-alive(HTTP/1.1 下可省略,因默认即 keep-alive);服务器若支持,可响应头里带 Keep-Alive: timeout=60, max=100 等,表示空闲多少秒或最多多少个请求后关闭。
优点减少 TCP 建连/断连次数,降低延迟、节省资源;同一域名下多个请求共用一个连接,更高效。
注意服务器需在一定时间内或请求数上限内关闭空闲连接,避免占满资源;客户端也可能主动发 Connection: close 要求关闭。

7.3 管道化(Pipelining)

项目说明
典型版本与长连接关系HTTP/1.1 中定义;与长连接并存——管道化依赖长连接:只有先建立并保持一条长连接,才能在该连接上「连续发多个请求不等响应」。二者不是二选一,而是「长连接是基础,管道化是在长连接上的可选优化」。
做法同一条长连接上,客户端不等待上一个响应返回就连续发出多个请求;服务器按收到顺序依次处理并按序回响应。
与普通长连接区别普通长连接是「发一个请求 → 等响应 → 再发下一个」;管道化是「连续发多个请求,再按序收多个响应」。
为何很少用容易遇到队头阻塞(Head-of-Line Blocking):若第一个请求的响应很慢或卡住,后面的响应都会被堵住,即使它们本身已经处理完;且中间代理、服务器实现不一,兼容性差。
现状浏览器中实际很少启用;HTTP/2 通过多路复用在一条连接上并行多个请求/响应流,从协议层避免了「一个慢请求堵住整条连接」的问题。

7.4 小结

  • 短连接:一请求一连接,用完即关;HTTP/1.0 默认;简单但延迟和建连开销大。
  • 长连接:一连接多请求;HTTP/1.1 默认 Keep-Alive;靠 Connection / Keep-Alive 控制。
  • 管道化:HTTP/1.1,依赖长连接、与长连接并存;在长连接上连续发请求不等响应;HTTP/1.x 下队头阻塞明显,实际少用;HTTP/2 多路复用替代该思路并解决队头阻塞。

八、Cookie 与 Session

HTTP 本身是无状态的:服务器不记录「上一次是谁、做了什么」。要在多次请求之间维持登录态、偏好等,需要「会话」机制。常见两种:

  • Cookie:数据存客户端,每次请求自动带上。
  • Session:数据存服务端,客户端只持有一个标识(通常用 Cookie 传 SessionID)。

Cookie 与 Session 流程示意

flowchart LR
    A1[首次访问] --> A2[Set-Cookie]
    A2 --> A3[浏览器存 Cookie]
    A3 --> A4[后续带 Cookie]
    A4 --> A5[服务器识别用户]
    B1[登录/首次] --> B2[建 Session]
    B2 --> B3[Set-Cookie SessionID]
    B3 --> B4[后续带 SessionID]
    B4 --> B5[服务器查 Session]

8.1 Cookie

项目说明
是什么由服务器通过响应头 Set-Cookie 下发给浏览器的一小块数据;浏览器会按域名、路径等规则自动保存,并在后续同域(同路径)请求里通过请求头 Cookie 自动携带。
流程首次:服务器响应里带 Set-Cookie: name=value; ... → 浏览器存下;之后:同一域名的请求自动带 Cookie: name=value; ...,服务器据此识别用户或读取状态。
常用属性Domain(生效域名)、Path(生效路径)、Expires / Max-Age(过期时间)、Secure(仅 HTTPS 发送)、HttpOnly(禁止 JS 读取,防 XSS 窃取)、SameSite(限制跨站携带,防 CSRF,如 Strict / Lax / None)。
限制单条 Cookie 约 4KB;每域名下条数有限(如几十到几百,因浏览器而异);总大小也有限制;存敏感信息需配合 Secure + HttpOnly
典型用途登录态(SessionID)、偏好设置、追踪标识等;敏感数据不宜明文放 Cookie,可只放 ID,真实数据放服务端(即 Session)。

8.2 Session

项目说明
是什么服务器为一次「会话」维护的一份服务端状态(如用户信息、购物车);客户端不存这份数据,只持有一个会话标识(SessionID);每次请求把 SessionID 发给服务器,服务器据此查出对应用户的会话数据。
SessionID 怎么传常见做法是用 Cookie 传:服务器在登录或首次访问时响应里带 Set-Cookie: JSESSIONID=xxx(或类似名),后续请求浏览器自动带该 Cookie,服务器用 xxx 查 Session。也可用 URL 参数或自定义头传递,但 Cookie 最常用。
客户端拿 SessionID 干什么用客户端不拿 SessionID 做任何业务逻辑,只是在每次请求里把它原样带给服务器。服务器收到后根据这个 ID 查到对应的 Session(用户信息、登录态等),从而知道「这次请求是谁、处于什么会话」。对客户端来说,SessionID 就是「下次请求时带给服务器的一张票」,真正使用它的是服务器
生命周期服务器创建 Session 时生成 SessionID 并写入 Cookie;在过期时间内或用户关闭浏览器(若为会话级 Cookie)前有效;服务端可主动使 Session 失效(如登出时删除对应 Session)。
优点敏感数据、大量数据存服务端,客户端只传 ID,相对安全;不受 Cookie 单条 4KB、条数等限制。
注意占用服务端内存或存储;多机/分布式时需共享 Session(如存 Redis、数据库),否则换机器就找不到该 Session。

8.3 Cookie 与 Session 的关系与区别

对比项CookieSession
数据存哪客户端(浏览器)服务端
客户端持有什么Cookie 的键值(可能有多条)通常仅一个 SessionID(常放在 Cookie 里)
大小与数量单条约 4KB,每域条数有限服务端可存较多数据,不受 Cookie 限制
安全性在客户端,可被窃取、篡改;需 HttpOnly、Secure、SameSite 等加固数据在服务端,相对安全;SessionID 泄露仍可能被冒用,故也需 Secure/HttpOnly
典型用法存偏好、追踪 ID,或仅存 SessionID存登录态、用户信息、购物车等敏感或大量数据

关系:Session 机制通常依赖 Cookie 传递 SessionID——Cookie 里只放一个 ID,真实会话数据在服务端用 Session 存。

8.4 小结

  • Cookie:服务端用 Set-Cookie 下发,浏览器自动存、自动带;可设 Domain、Path、Expires、Secure、HttpOnly、SameSite;有大小与条数限制;可单独用,也可只存 SessionID 配合 Session。
  • Session:数据在服务端,客户端只持 SessionID(常通过 Cookie 传);适合敏感或大量会话数据;分布式需共享存储。
  • 二者:不是二选一,常一起用——Cookie 传 SessionID,Session 存真实会话数据。

九、HTTPS 基础

HTTPS 在 HTTP 之下增加 SSL/TLS 层,对传输内容加密并对服务器做身份校验,可理解为「HTTP over TLS」。下面先对比 HTTP 与 HTTPS,再说明 TLS 协议、握手、加密方式等基础。

9.1 HTTP 与 HTTPS 对比

项目HTTPHTTPS
全称HyperText Transfer Protocol常称 HTTP Secure,即 HTTP + SSL/TLS
默认端口80443
URL 写法http://example.comhttps://example.com
传输内容明文(请求/响应、头部、body 均可见)加密(除 TLS 握手等外,应用层数据加密传输)
身份校验无;不验证对方身份通过数字证书验证服务器身份,防止冒充
完整性无;内容可被篡改而不易被发现有(如 MAC、签名等),可发现篡改
性能无加解密与握手开销有 TLS 握手与加解密开销;可通过会话复用、HTTP/2 等优化,通常可接受
浏览器表现无特殊提示地址栏锁标、证书有效时无警告;证书无效或过期会提示不安全
典型场景内网、测试、不涉密展示页生产环境、登录/支付、含敏感信息的页面;现代站点普遍要求 HTTPS

为何要用 HTTPS

  • 防窃听(明文可被截获)、防篡改(完整性校验)、防中间人(证书校验服务器身份)。
  • 合规与用户信任:敏感操作、登录、支付等通常要求 HTTPS。
  • 生产与敏感场景应使用 HTTPS;仅内网或临时测试可酌情用 HTTP。

9.2 SSL/TLS 协议

项目说明
SSL 与 TLS 是分开还是同时用分开使用,不是同时用。SSL 和 TLS 是两套不同协议(SSL 在先,TLS 是其后继);一次连接只会协商使用其中一种(如 TLS 1.2 或 TLS 1.3)。现在实际只用 TLS;说「SSL/TLS」多是习惯叫法,实际指的就是 TLS。
SSLSecure Sockets Layer,旧协议,已废弃;如 SSL 3.0 存在 POODLE 等漏洞,不应再使用。
TLSTransport Layer Security,现行标准,替代 SSL;日常说「SSL/TLS」时一般指 TLS。
版本建议仅启用 TLS 1.2、TLS 1.3;禁用 TLS 1.0/1.1 和所有 SSL。TLS 1.3 更简洁、更快、去掉不安全算法。

9.3 握手与性能

项目说明
握手目的协商 TLS 版本与加密套件、验证服务器证书、交换密钥(或协商出会话密钥),从而建立加密通道。
过程简述客户端发 ClientHello(版本、支持的套件等)→ 服务端回 ServerHello、证书、ServerHelloDone → 客户端校验证书、发密钥交换与 Finished → 服务端回 Finished,之后应用数据在加密通道中传输。
RTTTLS 1.2 完整握手约 2-RTT(两次往返);TLS 1.3 可 1-RTT,且支持 0-RTT 恢复(有安全权衡)。
性能握手与加解密有 CPU 开销;可通过 会话复用(Session Resumption)HTTP/2 单连接多路复用、CDN、硬件加速等优化;现代环境下性能通常可接受。

9.4 加密方式概览

类型作用常见算法说明
对称加密加密应用层数据(bulk 数据)AES、ChaCha20 等编解码快;密钥需安全协商,通常由握手阶段用非对称或 DH 等方式得到。
非对称加密密钥交换、身份验证(证书签名等)RSA、ECDHE、ECDSA 等公钥加密、私钥解密(或反之签名/验签);计算量大,一般只用于握手与密钥交换。
混合加密实际用法握手用非对称/密钥交换,数据用对称兼顾安全与性能:用非对称建立共享密钥,用对称加密业务数据。
哈希/完整性签名、完整性校验SHA-256、SHA-384 等证书签名、Finished 校验等;避免 MD5、SHA-1(已不推荐)。

9.5 HTTPS 请求完整流程(考点)

一次完整的 HTTPS 请求从「输入 URL」到「拿到响应」,大致经历以下步骤(面试/笔试常考)。

整体流程示意

flowchart LR
    A[DNS 解析] --> B[TCP 握手 443]
    B --> C[TLS 握手]
    C --> D[发 HTTP 请求]
    D --> E[返回响应]
    E --> F[关闭或复用]

TLS 握手(步骤 3)流程示意

flowchart LR
    T1[ClientHello] --> T2[ServerHello+证书]
    T2 --> T3[客户端校验证书]
    T3 --> T4[密钥交换]
    T4 --> T5[Finished]
    T5 --> T6[加密 HTTP 请求/响应]
步骤阶段说明
1DNS 解析浏览器根据域名(如 https://www.example.com)解析出服务器 IP 地址;可能走本地缓存、hosts、或 DNS 服务器。
2TCP 三次握手客户端与服务器在 443 端口建立 TCP 连接(SYN → SYN+ACK → ACK),为后续 TLS 和 HTTP 提供可靠传输。
3TLS 握手在已建立的 TCP 连接上进行 TLS 握手(见下),协商版本与加密套件、校验证书、交换密钥,建立加密通道。握手中通过 SNI(Server Name Indication)把要访问的域名发给服务端,便于同一 IP 多域名时选对证书。
4发送 HTTP 请求在 TLS 加密通道上,按 HTTP 协议发送请求(方法、URL、请求头、请求体等),内容已被加密。
5服务器处理并返回响应服务器解密请求、处理业务后,在加密通道上返回 HTTP 响应(状态码、响应头、响应体),内容同样加密传输。
6关闭连接双方可发送 TLS 关闭通知,然后 TCP 四次挥手释放连接;若为 Keep-Alive,连接可复用,下次同域请求可能跳过步骤 2、3。

TLS 握手(步骤 3)细化(常单独考)

TLS 握手在 TCP 连接建立后进行,目的是协商加密参数、校验证书、交换密钥,从而建立加密通道。五步概括如下。

步骤名称谁发/谁做内容与作用考点提示
1ClientHello客户端发送支持的 TLS 版本加密套件列表随机数等;服务端据此选择版本与套件。先发版本与套件,此时尚未带证书
2ServerHello + 证书服务端ServerHello:选定版本与加密套件、返回随机数;随后下发服务器证书(含公钥),供客户端校验证书并获取公钥。证书里带公钥,私钥只在服务端
3客户端校验证书客户端验证证书链有效期域名(如 SNI)等;通过后从证书中取出服务器公钥,用于后续密钥交换。链、有效期、域名、吊销(可选)
4密钥交换客户端 → 服务端客户端生成预主密钥,用服务器公钥加密后发给服务端(或走 ECDHE 等协商);只有持有服务器私钥的服务端能解密得到预主密钥;双方再用预主密钥(及 Hello 中的随机数)推导出相同的会话密钥,后续应用数据用会话密钥加密。预主密钥→会话密钥;常用 ECDHE
5Finished双方交换 Finished 消息,确认握手过程未被篡改;此后应用层数据均用会话密钥加密传输。握手结束,进入加密应用数据阶段

服务器密钥还有用吗?

有用,且必不可少。

  • 预主密钥是客户端生成的,但必须安全地让服务端也拿到,双方才能算出同一会话密钥。
  • 客户端用证书里的服务器公钥加密预主密钥再发送;只有拥有服务器私钥的服务端能解密,中间人拿不到。
  • 在密钥交换这一步,服务器公钥/私钥的作用就是:保护预主密钥只被客户端和服务端共享。
  • 握手完成后,业务数据用会话密钥加密,服务器密钥不再参与每包数据的加解密,但在握手阶段是必需的

小结:ClientHello → ServerHello+证书 → 客户端校验证书并取公钥 → 密钥交换得会话密钥 → Finished;之后 HTTP 在加密通道上传输。

HTTPS 请求流程小结DNS 解析 → TCP 建连(443)→ TLS 握手(证书校验 + 密钥交换)→ 加密的 HTTP 请求/响应;关闭时 TLS 结束再 TCP 挥手(或保持长连接复用)。


十、HTTPS 证书与安全实践

10.1 证书的作用与结构

为什么需要证书

HTTPS 握手需要服务器的公钥,但对方可能是攻击者冒充的。证书用来解决「对方是不是这个网站」:

  • CA 把「域名」和「公钥」绑在一起并签名。
  • 手机/浏览器确认签名有效、域名对、没过期后,才用证书里的公钥继续握手,密钥就不会交给冒充的中间人。
项目说明
作用通俗说:证书 = 「谁(域名/身份)」+ 「公钥」+ 「CA 的签名」。客户端用证书做两件事:一、确认「眼前这台服务器确实拥有这个域名对应的私钥」(因为只有私钥能配合证书里的公钥完成握手);二、从证书里拿到公钥,用来后续加密通信。服务器的私钥只保存在服务器自己那里,绝不会通过证书发给你。
常见格式X.509 是证书的通用格式。CA 用自己私钥对证书内容做一次「签名」;你的设备里已经预装了一批可信 CA 的公钥,用这些公钥可以验签:能验过就说明这张证书确实被该 CA 签发过、没被改过。

X.509 证书主要字段

字段含义
版本、序列号证书版本与唯一标识;序列号在吊销列表中用于指代某张证书。
签名算法CA 签发该证书时使用的算法(如 RSA-SHA256、ECDSA)。
颁发者(Issuer)签发该证书的 CA 名称;在链中用于找到「上一级」证书。
有效期(NotBefore / NotAfter)证书生效与过期时间;当前时间必须落在此区间内,否则视为无效。
主体(Subject)证书持有者(域名或组织);CN(Common Name)为早期主域名,现多依赖 SAN(Subject Alternative Name)列多个域名,以支持多域、泛域。
公钥服务器公钥,用于 TLS 密钥交换与后续加密;客户端从证书中提取此公钥。
扩展SAN(多域名)、密钥用途(Key Usage)、基本约束(Basic Constraints)等。
CA 数字签名对上述内容做哈希后用 CA 私钥签名;客户端用 CA 公钥验签,确保证书未被篡改且确由该 CA 签发。

10.2 证书链与 CA

证书链是什么

  • 服务器下发的是一证书:服务器证书 → 中间证书(可能多级)→ 根证书
  • 验证:从服务器证书开始,用「上一级公钥」验「下一级签名」,逐级到根证书;根证书必须在本地信任库中,否则整条链不认。
  • 通俗说:每一级都有人「盖章」,最后盖章的必须是系统自带的可信 CA。

证书链验证流程示意

flowchart LR
    A[服务器证书] -->|中间证书公钥验签| B[中间证书]
    B -->|根证书公钥验签| C[根证书]
    C --> D{根在信任库?}
    D -->|是| E[链可信]
    D -->|否| F[链不信任]
项目说明
链的验证过程① 用中间证书里的公钥,验证服务器证书的签名是否有效。
② 用根证书里的公钥,验证中间证书的签名是否有效。
③ 再看根证书是不是在本机「信任库」里、有没有过期。任一步失败就断开连接、报错。
为何要链根 CA 的私钥要严格保护、一般不直接给成千上万个网站签证书;所以根只给「中间 CA」签证书,再由中间 CA 给具体网站签。这样既安全,也方便以后换证书、换 CA。
CA证书颁发机构:专门负责给网站签发证书、并在需要时吊销证书的机构。公共 CA(如 Let's Encrypt、DigiCert)已被系统/浏览器内置信任;私有 CA(公司自己建的)需要你在设备上先安装它的根证书,才会被信任。
申请证书向 CA 提交 CSR(包含你的公钥和域名等信息),并完成域名验证(证明你确实控制这个域名),例如:在指定网址放一段指定内容(HTTP-01),或在 DNS 里加一条指定记录(DNS-01)。通过后 CA 才会给你签发证书。

10.3 证书验证、过期与吊销

客户端验证证书时,大致按下面顺序检查(有一项不通过就会连接失败或弹出「不安全」提示):

  1. 证书链:从服务器证书一路验到根证书,每一级签名都要对,且根证书必须在本地信任库里。
  2. 有效期:当前时间必须在证书的「生效时间」和「过期时间」之间。
  3. 域名:你访问的地址(如 api.example.com)必须出现在证书的域名列表(CN/SAN)里。
  4. 吊销(可选):这张证书没有被 CA 提前列入「作废名单」。
项目说明
过期过了证书上的过期时间就失效,浏览器会提示「证书已过期」。所以要在过期前续期并换上新证书;运维要盯紧到期时间(常见 90 天或 1 年),避免到期后全站报错。
吊销有时证书还没过期,但因为私钥泄露、域名不用了等原因,需要提前作废;作废后客户端就不应再信任这张证书。

怎么查「有没有被吊销」?常见两种方式对比

机制做法优点缺点
CRL(证书吊销列表)客户端从 CA 下载一份「已吊销证书名单」,看当前证书的序列号在不在名单里实现简单,可以缓存着用名单可能很大,更新有延迟;每次拉取有流量开销
OCSP(在线证书状态协议)客户端在握手时向 CA 的 OCSP 服务发一次请求:「这张证书有没有被吊销?」结果较新,只查这一张证书依赖网络,有延迟和隐私顾虑;OCSP 挂了可能影响建连
OCSP Stapling服务器在握手时主动带上一份「自己证书没被吊销」的 OCSP 证明(服务器事先向 CA 要好的),客户端不用自己去问 CA客户端不用连 CA,更快、更省、更保护隐私需要服务器侧配置,并定期向 CA 拉取这份证明

10.4 中间人攻击与防护

什么是中间人攻击(MITM)

  • 你在 A,服务器在 B,中间有攻击者 C;数据经 C 才到 B,C 可偷看、篡改、伪造
  • 例如公共 Wi‑Fi 下,攻击者成为「中间节点」:请求先到他再转服务器,他就能看到或改动请求和响应。

HTTP 下会怎样
HTTP 是明文传输,中间人可以直接看到你在访问什么、提交什么内容(如密码、表单),也可以篡改页面或响应。没有任何加密和身份校验,风险很大。

HTTPS 下为什么能防住(前提是正确校验证书)
HTTPS 会做两件事:加密身份校验

  • 加密:握手成功后,数据用协商出的密钥加密,中间人看不到明文。
  • 身份校验:服务器会出示证书,证明「我是这个域名对应的服务器」。证书是由可信 CA 签发的,且只有拥有该域名私钥的服务器才能完成 TLS 握手。中间人没有真服务器的私钥,所以无法冒充真服务器;客户端校验证书(链、有效期、域名、吊销)通过后,才会用证书里的公钥继续握手,这样密钥就不会交给中间人。

什么情况下 HTTPS 仍会被中间人攻破
如果客户端不校验证书、或校验证书失败后仍选择继续连接,就会出问题。例如:

  • 开发时为了抓包,在代码里「信任所有证书」或关掉证书校验,且这段逻辑被带到生产环境;
  • 用户访问时遇到证书错误(自签名、域名不匹配、过期等),被诱导点击「继续访问」「高级 → 继续前往」;
  • 设备上被安装了恶意根证书(如某些抓包工具、恶意软件),攻击者用这张根证书签一张「假」的服务器证书,客户端会认为它可信。

这些情况下,中间人可以让你和他建立一条「假」的 HTTPS 连接(他和你加密通信,他再和真服务器加密通信),他就能解密、查看、篡改你的数据。

防护要点总结

项目说明
必须用 HTTPS,并严格校验证书不要在生产环境关闭证书校验、不要「信任所有证书」或「信任所有主机名」;在公共 Wi‑Fi 等不可信网络下尤其不要关校验。服务端要配置完整证书链(把中间证书也发给客户端),否则客户端可能验不过。
HSTS(HTTP Strict Transport Security)服务器通过响应头告诉浏览器:「这个站以后只许用 HTTPS 访问」。浏览器在有效期内会强制用 HTTPS,即使用户输入了 http:// 也会自动跳成 https://,减少第一次访问被劫持或输错协议的风险。
其他页面用 HTTPS 时,里面的图片、脚本等资源也要用 HTTPS,不要出现「混合内容」(HTTPS 页里请求 HTTP 资源,可能被篡改)。要提醒用户不要随意点击「忽略证书警告」。高安全场景可再加证书锁定(见下)。

HTTPS 抓包原理(常考)

  • 抓包工具在本机/手机安装自己的根证书并被信任后,可解密 HTTPS。
  • 过程:浏览器 → 抓包工具(用该根证书签发「假」服务器证书)→ 真实服务器;浏览器信任该根证书,认为「假」证书合法,与抓包工具建 TLS;抓包工具再与真服务器建 TLS,从而解密、查看、篡改。
  • 结论:HTTPS 防的是「未信任的」中间人;用户一旦信任某 CA(如抓包根证书),该 CA 就能做中间人。生产环境不要信任此类证书;抓包仅限开发环境。

10.5 证书锁定(Certificate Pinning)与实践小结

证书锁定是什么意思

  • 在「证书链被系统信任」之外,客户端额外要求:该域名的证书(或公钥)必须与 App 里预置的 pin 一致。
  • :只认预置的证书/公钥,其他 CA 签的、系统信任的也不行。
  • 攻击者即使拿到「看起来合法」的证书(CA 被攻破、设备被装恶意根证书),pin 对不上则连接被拒绝。
项目说明
Pin 什么可以 pin 服务器证书本身、中间证书、或者公钥(或它们的哈希)。pin 公钥的好处是:证书到期续期时,只要公钥不变,不用改 App 里的 pin。
优点即使有人伪造证书、或 CA 出问题、或用户装了恶意根证书,只要不在你的 pin 列表里,就连不上;适合金融、支付等高安全场景。
缺点证书要换(续期、换 CA)时,pin 也要换,通常需要发新版本或通过配置更新;否则新证书对不上 pin,用户会连不上。
实践提前在客户端配置多组 pin(例如当前证书 + 即将启用的新证书),轮换时先发一版带新 pin 的 App,再在服务端切证书,最后再撤掉旧 pin,避免「只 pin 一张」导致换证当天大批用户失败。

实践小结

  • 服务端:用好证书、配全证书链、注意过期和吊销。
  • 客户端:绝不忽略证书错误、不信任所有证书;高安全场景可加证书锁定并做好 pin 轮换。
  • 再配合 HSTS、避免混合内容,整体安全性会高很多。

10.6 客户端(Android)HTTPS 使用要点

下面以 Android 为例,说明客户端在做 HTTPS 时要注意的证书校验、存储和错误处理。

项目说明
证书存在哪、分几种Android 把证书分成两类:
① 系统信任存储:手机出厂时自带的一批可信 CA 根证书,应用只能读、不能改;HttpsURLConnection / OkHttp 默认就是用这里来验证服务器证书链。
② 用户信任存储:用户自己在「设置 → 安全与隐私 → 加密与凭据 → 安装证书」里装的证书;装了之后,系统也会用它们参与 TLS 校验,所以用户装的根证书可以用来做抓包、企业代理等(等于信任了某个「中间人」)。
应用还可以自己维护一份私有证书(如放在 assets 或用 KeyStore),只给自定义的 TrustManagernetwork_security_config 用,不会进系统/用户的全局信任库。
默认会做什么校验使用 HttpsURLConnectionOkHttp 时,默认会:一、用系统信任库验证服务器证书链;二、做主机名校验(你请求的域名必须和证书里的域名一致)。生产环境绝对不能关掉校验、或写成「信任所有证书/所有主机名」,否则很容易被中间人攻击。
自签名/内网怎么测两种常见做法:一、把自签名 CA 或服务器证书装到用户信任存储,系统就会认;二、只在调试版里用自定义 TrustManager / SSLSocketFactory 信任你指定的证书,正式版必须去掉或用 BuildConfig 区分,避免正式包也信任自签名。
证书锁定怎么配OkHttp 时通过 CertificatePinner.add("host", "sha256/Base64…") 为域名配置 pin;同一域名可以配多个 pin 做备份。换证书时先发一版带新 pin 的 App,再在服务端切证书,最后再删旧 pin。
网络安全配置(Android 7+)network_security_config.xml 里可以统一配置:信任哪些用户/系统证书、只允许哪些 pin、是否允许明文(cleartext)等;这样不用在代码里写死「信任所有」,可以按 debug/release 或渠道区分策略。
出错时怎么处理遇到 SSLExceptionCertificateExpiredException(证书过期)、SSLPeerUnverifiedException(例如主机名对不上)等,要在界面上给用户明确提示(如「连接不安全」「证书已过期」),并打日志方便排查;不要静默吞掉异常,否则问题难定位。

小结

  • 生产环境严格校验证书、不能信任所有;自签名只用于调试/内网,不带到正式包。
  • 高安全场景可加证书锁定并做好 pin 轮换。
  • 配合网络安全配置和清晰错误提示,安全又易维护。

常考点速览

便于面试/笔试前快速过一遍,只列关键词与结论,细节见正文。

大类常考点结论/口诀
分层HTTP/HTTPS 所在层应用层;基于 TCP(80/443)
HTTP 特点无状态、为什么用 TCP无状态:不记上次请求;用 TCP:要可靠、有序传报文
方法GET vs POST、幂等与安全GET 幂等且安全、参数在 URL、可缓存;POST 非幂等、数据在 body、不缓存。幂等:多次相同请求效果一致;安全:不改服务器状态
状态码301 vs 302、401 vs 403、502/503/504301 永久/302 临时;401 未认证/403 无权限;502 上游坏/503 本机过载/504 上游超时
缓存强缓存 vs 协商缓存、命中顺序强缓存不发请求(max-age/Expires);协商缓存发请求带条件头,304 用本地。顺序:先判强缓存是否有效 → 无效再协商
缓存头Cache-Control、ETag vs Last-ModifiedCache-Control 优先于 Expires;ETag 优先于 Last-Modified;no-cache 是「要验证」不是「不缓存」
连接短/长连接、管道化短连接一请求一连接;长连接复用(HTTP/1.1 默认);管道化依赖长连接、HTTP/1.1 有队头阻塞,少用;HTTP/2 多路复用解决
Cookie/Session区别、SessionID 谁用Cookie 存客户端、Session 存服务端;SessionID 客户端只负责带给服务器,真正用的是服务器
CORS同源/跨域、简单请求 vs 预检同源=协议+域名+端口一致;跨域=任一项不同。简单请求不发 OPTIONS;非简单(自定义头、PUT/DELETE、application/json 等)先发 OPTIONS 预检
HTTPS 流程完整步骤DNS → TCP 三次握手(443)→ TLS 握手(证书+密钥交换)→ 加密 HTTP 请求/响应
TLSSSL vs TLS、握手几步SSL 与 TLS 分开用,现只用 TLS;握手:ClientHello → ServerHello+证书 → 校验证书 → 密钥交换 → Finished
证书链、验证项、CRL vs OCSP链:服务器证→中间证→根证,逐级验签;验证:链+有效期+域名+吊销;CRL 下载名单,OCSP 在线查,OCSP Stapling 由服务端带证明
MITM怎么防、何时仍会破用 HTTPS+严格校验证书;关校验、用户点继续、设备装恶意根证书时仍会破
证书锁定是什么、pin 什么只认预置的证书/公钥;pin 公钥利于轮换;换证要更新 pin,可多组 pin 平滑过渡
Android证书存哪、禁止做什么系统信任库+用户信任库;生产禁止关校验、禁止信任所有证书

小结

  • HTTP:无状态、请求-响应、基于 TCP,通过方法、状态码、头部和缓存等组成完整 Web 协议。
  • HTTPS:在 HTTP 上增加 TLS 加密与证书验证,是生产与敏感场景的标准选择。
  • 实际应用中:正确使用状态码与头部、合理设置缓存与连接、在客户端(如 Android)严格校验证书并可选使用证书锁定,即可兼顾性能与安全。