🔥 一句话解释 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 里把这个域名告诉服务器,让服务器知道发哪一套证书。

相关推荐
爱吃大芒果7 小时前
Flutter 主题与深色模式:全局样式统一与动态切换
开发语言·javascript·flutter·ecmascript·gitcode
小a杰.10 小时前
Flutter 进阶:构建高性能跨平台应用的实践与技巧
flutter
巴拉巴拉~~13 小时前
Flutter 通用轮播图组件 BannerWidget:自动播放 + 指示器 + 全场景适配
windows·flutter·microsoft
ujainu小13 小时前
Flutter 结合 shared_preferences 2.5.4 实现本地轻量级数据存储
flutter
走在路上的菜鸟14 小时前
Android学Dart学习笔记第十六节 类-构造方法
android·笔记·学习·flutter
hh.h.18 小时前
Flutter适配鸿蒙轻量设备的资源节流方案
flutter·华为·harmonyos
巴拉巴拉~~18 小时前
Flutter 通用下拉刷新上拉加载列表 RefreshListWidget:分页 + 空态 + 错误处理
flutter
走在路上的菜鸟18 小时前
Android学Dart学习笔记第十七节 类-成员方法
android·笔记·学习·flutter
走在路上的菜鸟19 小时前
Android学Dart学习笔记第十八节 类-继承
android·笔记·学习·flutter
巴拉巴拉~~19 小时前
Flutter 通用列表刷新加载组件 CommonRefreshList:下拉刷新 + 上拉加载 + 状态适配
前端·javascript·flutter