SvelteKit部署至DigitalOcean后Socket.IO 404错误求助
在DigitalOcean Droplet部署SvelteKit应用时Socket.IO 404错误解决方法
问题现象
在DigitalOcean Droplet上启动构建后的SvelteKit应用时,客户端请求GET http://???.??.???.???:3000/socket.io/?EIO=4&transport=polling&t=OMjACu5返回404错误。本地环境下执行npm run dev、npm run preview甚至node build/server.js都能正常运行。
服务器终端错误日志
Listening on 0.0.0.0:3000 Error: Not found: /socket.io/ at resolve (file:///root/svelteSPA/build/server/index.js:3403:18) at resolve (file:///root/svelteSPA/build/server/index.js:3290:34) at options.hooks.handle (file:///root/svelteSPA/build/server/index.js:3525:59) at respond (file:///root/svelteSPA/build/server/index.js:3288:42) server sveltekit (src\lib\server\index.js)
相关代码片段
客户端代码(src/lib/client/socketIo.js)
if (process.env.NODE_ENV === 'development') { socket = io('http://localhost:3000/'); console.log(process.env.NODE_ENV); } else { socket = io('http://???.??.???.???:3000/'); }
服务端代码(原版本)
import { handler } from './../../../build/handler.js?'; import express from 'express'; import { createServer } from 'http'; import { Server } from 'socket.io'; import cors from 'cors'; const app = express(); app.use(handler); app.use( cors({ origin: '*', methods: ['GET', 'POST'], allowedHeaders: ['Content-Type', 'Authorization'] }) ); const server = createServer(app); const io = new Server(server); const port = 3000; server.listen(port, () => { console.log(`Server running on ${port}`); });
svelte.config.js配置
import adapter from '@sveltejs/adapter-node'; export default { kit: { adapter: adapter() } };
问题原因
核心问题是中间件注册顺序错误:SvelteKit的handler被优先注册,导致所有请求(包括Socket.IO的/socket.io/路径)都先经过SvelteKit的路由处理逻辑,而SvelteKit无法识别该路径,直接返回404。同时CORS中间件在handler之后注册,无法对Socket.IO的请求生效。
修复方案
调整中间件注册顺序,并显式配置Socket.IO的CORS规则:
修改后的服务端代码
import { handler } from './../../../build/handler.js'; import express from 'express'; import { createServer } from 'http'; import { Server } from 'socket.io'; import cors from 'cors'; const app = express(); // 1. 先注册CORS中间件,确保所有请求都能获取跨域权限 app.use( cors({ origin: '*', methods: ['GET', 'POST'], allowedHeaders: ['Content-Type', 'Authorization'] }) ); // 2. 再注册SvelteKit的handler,让它处理非Socket.IO的请求 app.use(handler); // 3. 为Socket.IO显式配置CORS(可选但建议,避免跨域问题) const server = createServer(app); const io = new Server(server, { cors: { origin: '*', methods: ['GET', 'POST'] } }); const port = 3000; server.listen(port, () => { console.log(`Server running on ${port}`); });
额外检查项
- 确认部署环境中
process.env.NODE_ENV为production,可通过console.log(process.env.NODE_ENV)验证客户端连接地址是否正确 - 开放Droplet的3000端口:执行
ufw allow 3000(Ubuntu防火墙) - 启动命令需正确:先执行
npm run build完成构建,再运行node build/server.js启动应用(原命令node build路径错误)
内容的提问来源于stack exchange,提问作者Kristian
相关产品推荐
相关产品推荐

