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
相关产品推荐
相关产品推荐

