Express.js 偶现Cannot GET /错误:双服务端口冲突问题排查
问题描述
期望实现:
- 访问
http://localhost:3000/app时展示myFile.html文件内容 - 访问
http://localhost:3000/api时返回字符串"It worked!"
当前实现了两个文件:
App.js 代码
const http = require('http'); const fs = require('fs'); const express = require('express'); const app = express(); app.use(express.static("./")); app.get("/app", (request, response) => { fs.readFile("./myFile.html", "utf8", (err, html) => { if (err) { response.status(500).send("A problem occured" + err); } response.send(html); }) }); app.listen(process.env.PORT || 3000, () => console.log("App available on http://localhost:3000"));
server.js 代码
const http = require('http'); const fs = require('fs'); const express = require('express'); const app = express(); app.use(express.static("./")); app.get("/api", (request, response) => { response.send("It worked!"); }); app.listen(process.env.PORT || 3000, () => console.log("App available on http://localhost:3000"));
遇到的问题:服务有时正常运行,有时出现Cannot GET /app或Cannot GET /api错误。先后运行node App.js和node server.js时,最后启动的服务能正常工作,但偶尔两个服务又都能运行,无固定规律。
问题原因
同一端口(这里是3000)在同一时间只能被一个进程占用。正常情况下第二个启动的服务会因为端口被占用而启动失败,但偶尔出现的"两个都能运行"的情况,大概率是前一个服务的端口还没完全释放(系统端口TIME_WAIT状态延迟),但这种状态不稳定,最终还是会出现端口冲突导致其中一个服务无法处理请求。
把两个路由拆在两个独立的Express应用里,每个都监听同一个端口,这本身就是错误的做法——两个服务无法同时正常处理各自的路由请求。
解决方案
把两个路由合并到同一个Express应用中,只启动一个服务即可。优化后的代码示例:
const express = require('express'); const path = require('path'); const app = express(); // 保留静态文件服务(如果需要的话) app.use(express.static("./")); // /app 路由:返回myFile.html app.get("/app", (req, res) => { const filePath = path.join(__dirname, 'myFile.html'); res.sendFile(filePath, (err) => { if (err) { res.status(500).send(`加载文件失败: ${err.message}`); } }); }); // /api 路由:返回指定字符串 app.get("/api", (req, res) => { res.send("It worked!"); }); app.listen(process.env.PORT || 3000, () => { console.log("App available on http://localhost:3000"); });
优化点说明
- 用
res.sendFile替代手动fs.readFile,Express会自动处理文件读取和响应头设置,代码更简洁可靠 - 用
path.join(__dirname, 'myFile.html')确保文件路径的正确性,避免相对路径带来的问题 - 合并路由到同一个应用,彻底解决端口冲突问题
运行方式
删除原来的App.js和server.js,创建新的app.js(或任意文件名),写入上述代码,然后执行:
node app.js
现在访问http://localhost:3000/app和http://localhost:3000/api都能正常工作,不会再出现端口冲突导致的路由无法访问问题。
内容的提问来源于stack exchange,提问作者ICantCode
相关产品推荐
相关产品推荐

