Express服务器处理GET请求时无响应,页面无法加载求助
Hey there! 作为经常折腾Express的开发者,我看完你的代码后发现了几个很可能导致服务器卡住、请求无响应的问题,咱们一步步来解决:
1. Cookie Parser 调用错误(最可能的元凶)
你这里写了:
app.use(cookieParser);
但cookieParser是一个需要调用执行的函数,它返回处理cookie的中间件。少了括号的话,中间件根本没正确加载,会导致后续依赖cookie的express-session中间件卡死请求——这也是为什么你的GET请求回调里的console.log("am here")根本没执行,请求还没走到路由就被卡住了。
修复方式:
// 先确认已正确引入 const cookieParser = require("cookie-parser"); // 加上括号调用 app.use(cookieParser());
2. 静态文件路径配置错误
你用了相对路径../public来设置静态文件目录:
app.use(express.static("../public"));
Node.js里的相对路径是相对于启动服务器时的终端目录,而不是app.js所在的目录,这很容易导致路径找不到。更稳妥的方式是用__dirname(当前文件的绝对路径)来拼接:
修复方式:
// 先引入path模块 const path = require("path"); // 替换原来的静态文件中间件 app.use(express.static(path.join(__dirname, "public")));
(假设你的public文件夹和app.js在同一个根目录下)
3. Admin路由POST请求的重复响应问题
在你的admin.js的POST路由里,不管try块里有没有发送响应,最后都会执行res.redirect("/admin"):
try { const user = await User.create({ username, hashedPassword }); res.status(201).json({ message: "User Created", user }); } catch (error) { // ...错误处理 } res.redirect("/admin"); // 这里会重复发送响应
这会触发Cannot set headers after they are sent to the client的错误,虽然你说控制台没报错,但如果前面的cookieParser问题解决后,这个错误就会显现出来。另外,你这个POST路由看起来是注册用户,但逻辑里直接创建用户后又返回JSON再跳转,逻辑有点混乱,应该统一响应方式:
修复方式:
router.post("/admin", async (req, res) => { const { username, password } = req.body; console.log(username, password); try { // bcrypt.hash需要传入盐轮数(比如10),否则会有警告 const hashedPassword = await bcrypt.hash(password, 10); await User.create({ username, hashedPassword }); // 注册成功后跳转到admin登录页或者面板 res.redirect("/admin"); } catch (error) { if (error.code === 11000) { // 把错误信息传递到登录页面显示 res.render("admin/login", { locals: { title: "Admin Page" }, layout: adminLayout, error: "用户名已被使用,请换一个" }); } else { console.error(error); res.status(500).send("服务器内部错误"); } } });
4. 小细节优化:根路由规范写法
你的main.js里根路由写的是:
router.get("", async (req, res) => { ... });
虽然Express会把空路径解析为根路径/,但写全router.get("/", ...)会更规范,避免后续可能的路由匹配问题。
排查步骤建议
- 先修复Cookie Parser的问题,这是最可能导致请求无响应的核心原因;
- 启动服务器,测试
localhost:PORT,看console.log("am here")是否打印; - 如果还是有问题,检查MongoDB连接是否正常(虽然你的
start函数里已经处理了连接错误,但可以确认CONNECTION环境变量是否正确); - 最后修复静态文件路径和admin路由的响应问题。
按照这个顺序调整后,应该就能解决页面无法加载的问题啦!
备注:内容来源于stack exchange,提问作者Zineb Jinari

