🔥 一句话解释 SNI

SNI 是 TLS 握手时,客户端提前告诉服务器:"我想访问的是哪一个域名"。

它的作用是让服务器在 TLS 握手阶段就能知道要给哪个域名的证书。


🎯 为什么需要 SNI?

因为现在很多网站是 多域名共享同一个 IP。

例如:

diff 复制代码
1.2.3.4 上托管了:
- api.a.com
- img.a.com
- pay.a.com

如果没有 SNI:

客户端连接 1.2.3.4:443 → TLS 握手开始

服务器此时 不知道你想访问哪个域名的证书

→ 就没法送对证书

→ 导致握手失败

所以 TLS 扩展 "SNI" 就诞生了。


🧠 SNI 在 TLS 握手里到底发生了什么?

TLS 1.2 / 1.3 都一样,基本流程是:

markdown 复制代码
ClientHello:
    - TLS Versions
    - Cipher Suites
    - Extensions:
        - SNI = "api.example.com"   ← 就是这里!
        - ALPN (比如 h2/h3)
        - ...

服务器收到 ClientHello 后,看到 SNI:

复制代码
哦,你访问的是 api.example.com!
那我给你发 api.example.com 的证书

然后握手继续。


🔥 SNI 与 "IP 直连(DNS Mapping)" 有什么关系?

这是你现在最关心的一点:

你做 DNS 优化时会把域名替换成 IP:

arduino 复制代码
https://api.example.com/user
→
https://203.107.1.1/user   (IP直连)

如果你 不加 Host header:

服务器会认为:

复制代码
你要访问 203.107.1.1
那我发给你"203.107.1.1"对应的证书(基本不存在)
→ TLS 握手立即失败

所以你必须:

less 复制代码
req.setValue("api.example.com", forHTTPHeaderField: "Host")

⚠️ 更重要的是:
"Host" header 会被 URLSession 自动用作 SNI 的域名。

所以 TLS 握手会变成:

ini 复制代码
SNI = "api.example.com"

→ 即使你是连的 IP,TLS 仍然能拿到对应的域名证书

→ 握手成功

这就是 IP 直连 + HTTPS 能工作的原因。


🎯 用一句更工程化的话总结:

SNI 就是 TLS 握手阶段的 Host header。

客户端会在 ClientHello 里把这个域名告诉服务器,让服务器知道发哪一套证书。

相关推荐
好的佩奇16 小时前
Dart 之类型系统
flutter·dart
恋猫de小郭1 天前
Dart 3.15 新特性:this 终于支持类型提升了
android·前端·flutter
FungLeo2 天前
成为全栈·Flutter App 篇·主题与可访问性:深浅色、大字号和触控体验
flutter·移动开发·深色模式·可访问性·成为全栈·大字号适配
用户95421573334853 天前
只是选个照片,怎么留下了这么多访问记录?Flutter 图片选择器排查与优化实录
flutter
FungLeo3 天前
成为全栈·Flutter App 篇·第四批复盘:复用了什么,移动端又新增了什么
flutter·移动开发·跨端开发·成为全栈·api契约·全栈复盘
jason.zeng@15022073 天前
使用vscode+flutter开发android程序(入门)
android·vscode·flutter
jason.zeng@15022073 天前
Flutter 项目标准分层目录(repository/dto/page,对齐后端思想)
flutter
程序员老刘5 天前
跨平台开发地图 | 2026年10月
flutter·ai编程·客户端
林瞅瞅5 天前
Flutter 开发环境从零搭建与调试记录
flutter
FungLeo5 天前
成为全栈·Flutter App 篇·Markdown 编辑器:编辑、预览与离开保护
flutter·移动开发·markdown编辑器·表单设计·成为全栈·草稿保存