map指令必须置于http块顶层,不可在server或location内;标准写法为map $http_upgrade $connection_upgrade { default upgrade; '' close; },并配合proxy_http_version 1.1、proxy_set_header upgrade $http_upgrade和proxy_set_header connection $connection_upgrade三步透传。

直接在 Nginx 的 http 块顶层写这个 map 指令,不能放在 server 或 location 里,否则启动会报错“unknown variable”。
必须放对位置:http 级别
map 指令只允许出现在 http 块中,它是全局变量定义,Nginx 在加载配置时就完成映射关系构建。写在 server 或 location 内属于语法错误,服务根本起不来。
- ✅ 正确位置:
http { map $http_upgrade $connection_upgrade { ... } server { ... } } - ❌ 错误写法:
server { map ... }或location /ws { map ... }
标准写法与含义
最常用且稳妥的写法是:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
它表示:
- 只要请求头里有
Upgrade(哪怕值是websocket、h2c甚至foo),变量$connection_upgrade就设为upgrade - 仅当
$http_upgrade完全没传、或传了空字符串时,才设为close -
default行不可省略,否则未匹配时变量为空,可能导致 Connection 头缺失,后端握手失败
配合 proxy 使用的关键三步
光定义变量没用,必须在 location 中透传给后端:
-
proxy_http_version 1.1;—— WebSocket 必须基于 HTTP/1.1,强制协议版本 -
proxy_set_header Upgrade $http_upgrade;—— 原样转发原始 Upgrade 头(不是硬写websocket) -
proxy_set_header Connection $connection_upgrade;—— 用 map 计算出的值设置 Connection,避免误发upgrade给普通 HTTP 请求
后端兼容性微调
如果后端(比如某些 Spring Boot 版本或旧版 Node.js)对 Connection: close 不友好,期望该头为空,可把空值映射改为空字符串:
map $http_upgrade $connection_upgrade {
default upgrade;
'' '';
}
这样在非 Upgrade 请求中,Connection 头就不出现,由 Nginx 默认行为接管连接管理。











