AWS EC2部署WebSocket Server:浏览器连403错误,Python正常
我之前也踩过这个一模一样的坑!Python脚本用websocket.create_connection能正常连EC2上的WebSocket服务,结果Chrome里用JS就报403,安全组都开全了还是不行。后来才发现问题根本不在网络层面,而是浏览器和服务端的规则不匹配,给你列几个最常见的原因和解决办法:
跨域(CORS)配置没跟上
浏览器会严格做CORS校验,但Python的客户端不会触发预检请求。如果你的WebSocket服务没配置允许前端域名的CORS头,浏览器直接就会返回403。
举个例子,如果你用的是Python的websockets库,得在连接处理里加响应头:async def handle_client(websocket, path): # 添加上允许跨域的头,生产环境别用*,换成你的前端域名 websocket.response_headers['Access-Control-Allow-Origin'] = '*' websocket.response_headers['Access-Control-Allow-Methods'] = 'GET, OPTIONS' websocket.response_headers['Access-Control-Allow-Headers'] = 'Sec-WebSocket-Key, Sec-WebSocket-Version' # 接下来处理你的业务逻辑服务端对请求头做了校验
有些WebSocket服务会检查Origin或者Sec-WebSocket-Protocol这些头,Python脚本可能没带这些头(或者带的刚好符合要求),但浏览器会自动发送,不符合校验就被拦了。
解决办法要么改服务端的校验规则,允许浏览器的请求头;要么在前端JS里指定符合要求的协议头:// 比如服务端要求指定协议,就这么写 var ws = new WebSocket('ws://你的EC2公网IP:端口', ['your-protocol-name']);EC2内部的防火墙/反向代理搞事情
安全组全开不代表实例内部没限制!比如iptables可能拦了端口,或者你用了Nginx反向代理但没配置WebSocket转发规则。- 检查
iptables:
如果没看到允许的规则,就加一条:sudo iptables -L -n | grep 你的WebSocket端口sudo iptables -A INPUT -p tcp --dport 端口号 -j ACCEPT - 如果用Nginx,必须加WebSocket的转发配置:
location /ws { proxy_pass http://localhost:你的WebSocket端口; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Origin $http_origin; # 关键,不然跨域会被拦 }
- 检查
混合内容策略限制
如果你的前端是HTTPS的,WebSocket用ws://(非加密),浏览器会因为混合内容安全策略阻止连接,返回403。
解决办法要么把WebSocket升级成wss://(配SSL证书),要么在前端页面加个元标签临时允许(生产环境不推荐):<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
既然你已经查明了问题原因,看看是不是上面某一条?要是还有其他细节,随时补充我再帮你捋!
内容的提问来源于stack exchange,提问作者rampatowl

