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

HTTPS环境下Socket.io与Node.js后端连接失败求助

解决HTTPS环境下Socket.io连接失败问题

核心问题分析

从curl返回的error:0A00010B:SSL routines::wrong version number错误可以看出,你的后端端口5000实际上在提供HTTP服务,而非HTTPS服务,导致客户端发起TLS握手时收到HTTP响应,触发协议不匹配错误。结合代码来看,主要问题出在服务器监听逻辑和证书加载方式上。


解决步骤

1. 修复证书/密钥的读取方式

.pem格式的证书和密钥是二进制文件,使用utf8编码读取会破坏文件内容,导致SSL握手失败。修改读取逻辑,去掉utf8参数(默认返回Buffer,是正确的加载方式):

const credentials: https.ServerOptions = {
    key: fs.readFileSync(__dirname+'/sslcert/key.pem'),
    cert: fs.readFileSync(__dirname+'/sslcert/cert.pem'),
};

2. 修正服务器监听逻辑

你之前通过io.listen(5000)启动服务,这会创建一个全新的HTTP服务器,而非复用你配置好的HTTPS服务器。正确的做法是让HTTPS服务器监听端口,Socket.io挂载在该服务器上:

const httpsServer = https.createServer(credentials, app);
const io = new Server(httpsServer, {
    cors: {
        origin: `https://localhost:3000`,
        methods: ["GET", "POST"] // 明确允许的HTTP方法
    },
});
// 让HTTPS服务器监听端口
httpsServer.listen(5000, () => {
    console.log('HTTPS Server running on https://localhost:5000');
});

io.on('connect', (socket) => {
    console.log('Client connected:', socket.id);
});

3. 客户端添加证书验证跳过配置

由于使用自签名证书,客户端需要禁用证书校验才能正常连接:

import {io, Socket} from 'socket.io-client';

const socket = io("https://localhost:5000", {
    query: {username: "foo"},
    rejectUnauthorized: false // 跳过自签名证书验证
});
socket.on('connect', () => console.log("Socket connected successfully"));

4. 重新生成符合标准的自签名证书

如果浏览器仍提示证书不安全,生成证书时添加localhost的主题名称和SAN扩展(避免现代浏览器的安全拦截):

openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout key.pem -out cert.pem -subj "/CN=localhost" -addext "subjectAltName=DNS:localhost"

验证方法

修改完成后,先测试HTTPS服务是否正常:

curl https://localhost:5000 --insecure -vvv

如果返回正常的HTTP响应(比如404,因为你没有配置路由),说明HTTPS服务已正确启动。再启动前端,Socket.io连接应该能正常建立。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 22:50:13