You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DigitalOcean应用平台NGINX环境WebSocket连接报301错误

解决DigitalOcean App Platform上WebSocket连接301重定向问题

核心原因分析

浏览器的WebSocket API不会自动跟随301重定向,而你的请求wss://example.com/ws返回301,大概率是路径匹配规则不兼容导致的:

  • NGINX配置中WebSocket的location是/ws/(带尾斜杠),但前端请求的是/ws(不带尾斜杠),NGINX无法匹配,进而触发重定向或错误路由。
  • 后端代码仅判断/ws路径,若请求被重定向到/ws/,会因路径不匹配返回400,而Postman能成功是因为它会自动跟随重定向并调整请求路径。

具体修复步骤

1. 修正NGINX配置

修改前端容器的NGINX配置,确保带/不带尾斜杠的WebSocket请求都能正确代理到后端:

server {
    listen 80;
    server_name example.com;

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

    location /api/ {
        proxy_pass http://backend-api:5000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }

    # 匹配/ws和/ws/请求,统一转发到后端/ws路径
    location /ws {
        rewrite ^/ws/?$ /ws break;
        proxy_pass http://backend-api:5000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_cache_bypass $http_upgrade;
    }

    # 同理处理/game路径
    location /game {
        rewrite ^/game/?$ /game break;
        proxy_pass http://backend-api:5000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_cache_bypass $http_upgrade;
    }
}

2. 兼容后端路径判断

修改后端.NET Core代码,同时支持带/不带尾斜杠的路径:

app.Use(async (context, next) =>
{
    // 移除路径末尾的斜杠,统一判断
    var requestPath = context.Request.Path.ToString().TrimEnd('/');
    if (requestPath == "/ws" || requestPath == "/game")
    {
        if (context.WebSockets.IsWebSocketRequest)
        {
            WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync();
            string connId = Guid.NewGuid().ToString();
            var webSocketManager = app.Services.GetRequiredService<WebSocketMan>();
            webSocketManager.AddSocket(connId, webSocket);
            await webSocketManager.HandleWebSocketCommunication(webSocket, connId, context);
        }
        else
        {
            context.Response.StatusCode = 400;
        }
    }
    else
    {
        await next();
    }
});

3. 优化DigitalOcean App Platform路由(可选)

如果不想通过前端NGINX代理后端请求,可以直接在App Platform的路由设置中配置路径分流:

  • 添加路由规则:/api/*、/ws、/game 指向后端组件
  • 保留/*指向前端组件
    这样可以跳过前端代理层,直接由平台负载均衡转发请求,减少潜在的路径匹配问题。

4. 验证请求详情

在浏览器开发者工具的Network标签中,查看WebSocket请求的完整响应头,确认301是否消失,以及请求是否正确到达后端。

内容的提问来源于stack exchange,提问作者myaccountname

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 01:53:09