Nginx代理WebSocket失败的完整排查过程

 更新时间:2025年11月14日 08:55:24   作者:不会写程序的未来程序员  
在开发基于 WebSocket 的实时应用时,使用 Nginx 作为反向代理是常见做法,可是我遇见了后端直连 WebSocket 成功,通过 Nginx 代理却失败,本文将完整复盘一次真实排查过程,带你避开所有坑,需要的朋友可以参考下

问题现象

  • 后端服务运行在 192.168.1.10:8080,提供 WebSocket 接口 /ws/xxx
  • 使用 wscat 或浏览器直连 ws://192.168.1.10:8080/ws/xxx ✅ 成功
  • 配置 Nginx 反向代理后,前端连接 ws://localhost/ws/xxx ❌ 失败
  • 浏览器 Network 面板显示 WebSocket 请求失败(无 101 响应)
  • 关键线索:Nginx 的 access_log没有任何 WebSocket 请求日志

初步怀疑:Nginx 配置错误?

首先检查 Nginx 配置:

map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
}

upstream webservers {
    server 192.168.1.10:8080;
}

server {
    listen 80;
    server_name localhost;

    location /ws/ {
        proxy_pass http://webservers/ws/;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "$connection_upgrade";  # ⚠️ 这里有坑!
        proxy_read_timeout 3600s;
    }
}

常见错误包括:

  • Connection 头加了双引号 → 变成字面量
  • map 没放在 http 块顶层
  • 缺少 proxy_buffering off

但即使修正这些,日志依然为空,说明:请求根本没到 Nginx!

关键转折:前端页面来源被忽略

通过 docker ps 确认端口映射正常:

nginx     0.0.0.0:80->80/tcp

但发现一个致命细节:

前端页面是通过虚拟机 IP 打开的:http://192.168.228.128/
而 WebSocket 地址写的是:ws://localhost/ws/xxx

问题本质

  • 浏览器中的 localhost 永远指向客户端本机(Windows 电脑)
  • 而我的 Nginx 运行在 虚拟机中
  • 所以 ws://localhost/... 实际请求的是 我 Windows 的 80 端口,而非虚拟机!

→ 请求压根没发给 Nginx,自然没有日志!

解决方案

方法 1:显式指定虚拟机 IP(临时可用)

// 前端 JS
const ws = new WebSocket('ws://192.168.228.128/ws/xxx');

立即生效!

方法 2:使用相对路径(推荐 ✅)

// 自动继承当前页面的 host
const ws = new WebSocket('/ws/xxx');

优势:

  • 页面在 http://localhost → 连 ws://localhost
  • 页面在 http://192.168.228.128 → 连 ws://192.168.228.128
  • 部署到域名也无需修改代码

附:正确的 Nginx 配置模板

http {
    # 必须在 http 块顶层!
    map $http_upgrade $connection_upgrade {
        default upgrade;
        '' close;
    }

    upstream backend {
        server host.docker.internal:8080;  # Docker Desktop 推荐
        # 或 server 192.168.1.10:8080;
    }

    server {
        listen 80;
        server_name _;  # 匹配任意 Host

        location / {
            root /usr/share/nginx/html;
            index index.html;
        }

        location /ws/ {
            access_log /var/log/nginx/ws_access.log;
            proxy_pass http://backend/ws/;
            proxy_http_version 1.1;
            proxy_buffering off;          # 必须关闭
            proxy_cache off;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $connection_upgrade;  # 无引号!
            proxy_read_timeout 3600s;
        }
    }
}

经验总结

问题类型排查要点
Nginx 无日志先确认请求是否真的发到了 Nginx(检查前端地址、端口映射)
WebSocket 426检查 UpgradeConnection 头是否正确传递
前端连接失败确保 WebSocket 地址与页面同源(避免硬编码 localhost
Docker 环境host.docker.internal 代替 IP 更可靠

最后提醒

localhost 在前端代码中 ≠ 你的服务器!
它永远指向用户浏览器所在的机器

开发时务必注意页面来源与 WebSocket 目标的匹配关系,这是 WebSocket 代理失败的最高频原因

结语

从“426 Upgrade Required”到“连接成功”,看似是配置问题,实则是网络拓扑理解偏差。希望本文能帮你少走弯路!

到此这篇关于Nginx代理WebSocket失败的完整排查过程的文章就介绍到这了,更多相关Nginx代理WebSocket失败内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 详细nginx多域名配置的方法

    详细nginx多域名配置的方法

    Nginx绑定多个域名,可通过把多个域名规则写一个配置文件里实现,也可通过分别建立多个域名配置文件实现,为了管理方便,建议每个域名建一个文件,有些同类域名则可写在一个总的配置文件里。下面这篇文章就来详细看看nginx多域名配置的方法,有需要的朋友们可以参考。
    2016-12-12
  • Nginx实现流量拷贝的示例代码

    Nginx实现流量拷贝的示例代码

    在生产环境中,我们经常需要将流量拷贝到预上线环境或测试环境,以便进行各种验证和测试,本文主要介绍了Nginx实现流量拷贝,具有一定的参考价值,感兴趣的可以了解一下
    2025-07-07
  • nginx http模块数据存储结构小结

    nginx http模块数据存储结构小结

    这篇文章主要介绍了nginx http模块数据存储结构小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-02-02
  • 解析nginx server_name的具体使用

    解析nginx server_name的具体使用

    nginx server_name对于正确配置虚拟主机非常重要,本文主要介绍了解析nginx server_name的具体使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-08-08
  • 使用nginx配置基于域名的虚拟主机实现​

    使用nginx配置基于域名的虚拟主机实现​

    这篇文章主要介绍了nginx配置基于域名的虚拟主机实现​,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-10-10
  • CentOS7下非编译安装Nginx的图文教程

    CentOS7下非编译安装Nginx的图文教程

    这篇文章主要为大家详细介绍了CentOS7下非编译安装Nginx的图文教程,文中通过示例图片进行了详细讲解,有需要的小伙伴可以跟随小编一起学习一下
    2023-10-10
  • Nginx配置统计流量带宽请求及记录实时请求状态的方法

    Nginx配置统计流量带宽请求及记录实时请求状态的方法

    这篇文章主要介绍了Nginx中配置统计流量带宽请求及记录实时请求状态的方法,分别用到了ngx_req_status和ngx_realtime_request模块,需要的朋友可以参考下
    2016-01-01
  • 一文详解如何高效查找与管理Nginx进程

    一文详解如何高效查找与管理Nginx进程

    在Linux系统中,Nginx是一个非常流行的Web服务器和反向代理服务器,要查找和管理Nginx进程,你可以使用多种命令行工具和技巧,以下是一些常用的方法,需要的朋友可以参考下
    2025-08-08
  • Linux部署Nginx实现反向代理的方法步骤

    Linux部署Nginx实现反向代理的方法步骤

    Nginx 是一种常用、轻型且快速的 Web 服务器, 它可以在 Linux 和 Windows 上运行,并且可以配置为反向代理服务器,本文主要介绍了Linux部署Nginx实现反向代理的方法步骤,感兴趣的可以了解一下
    2023-08-08
  • Nginx出现403错误,应该如何解决

    Nginx出现403错误,应该如何解决

    这篇文章主要介绍了Nginx出现403错误,应该如何解决?具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03

最新评论