Nginx中map指令必须在http块顶层定义,用于将$http_upgrade动态映射为$connection_upgrade变量:非空时设为upgrade,为空时设为close,再通过proxy_set_header Connection $connection_upgrade安全透传,避免硬编码Connection: upgrade导致普通HTTP异常或WebSocket升级失败。

关键在于用 map 指令把客户端的协议意图(是否带 Upgrade 头)转化为 Nginx 能安全转发的 Connection 值,避免硬编码导致普通 HTTP 请求异常或 WebSocket 升级失败。
为什么不能直接写死 Connection: upgrade
Nginx 默认会过滤掉 Connection 头中非常规值,如果固定设为 upgrade:
- 普通 HTTP 请求也会被强制带上
Connection: upgrade,后端可能拒绝或误判 - 违反 HTTP/1.1 规范,某些代理或防火墙会直接中断连接
- 无法区分真实 WebSocket 升级请求和常规请求,失去协议路由能力
map 指令如何做动态映射
在 http 块顶层定义映射规则:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
这个配置的含义是:
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
-
$http_upgrade是 Nginx 自动提取的请求头值(如websocket),为空表示没发 Upgrade 请求 -
default upgrade:只要$http_upgrade非空(哪怕值是foo),就设$connection_upgrade为upgrade -
'' close:仅当请求头完全缺失或为空字符串时,才设为close,让连接按普通 HTTP 流程处理
在 location 中正确使用映射结果
有了变量后,必须在 proxy 场景中显式透传:
-
proxy_http_version 1.1;:WebSocket 必须基于 HTTP/1.1 -
proxy_set_header Upgrade $http_upgrade;:原样转发原始 Upgrade 头 -
proxy_set_header Connection $connection_upgrade;:用 map 计算出的值设置 Connection 头
这样既保留了升级信号,又确保非 WebSocket 请求不会触发非法头,Nginx 不重启也能响应协议变化。
常见配置陷阱提醒
容易忽略但影响上线的细节:
-
map块必须放在http级别,不能嵌套在server或location内,否则报错 -
default行不能省略,否则未匹配时变量为空,可能导致 Connection 头丢失 - 如果后端是 Node.js、Spring Boot 等框架,需确认其对
Connection: close的兼容性,部分实现期望空值而非close,此时可将''对应值改为''(空字符串)










