Node.js接口返回HTML而非JSON的问题求助
Node.js接口返回HTML而非JSON的问题求助
兄弟,我一眼就瞅出问题所在了——你的路由挂载顺序搞反了!
先看你的代码:你把SPA的兜底路由app.get("*", ...)放在了/test接口的前面,而Express的路由是按代码书写顺序从上到下匹配的。也就是说,当客户端请求/test时,第一个匹配到的是通配所有路径的*,直接返回了React的index.html,根本轮不到后面的/test接口返回JSON数据。
至于开发环境为什么没问题?大概率是你用了React的开发服务器(比如create-react-app的start命令),通过proxy配置把API请求转发到Node服务,这时候前端路由和Node的API路由是分开处理的,不会出现路由匹配冲突。但到了生产环境,Node服务器同时托管静态文件和API,路由顺序的问题就直接暴露了。
解决方案:调整路由顺序
把静态文件托管和SPA兜底路由移到所有API路由的最后面,也就是放到app.listen之前。修改后的代码结构如下:
const express = require("express"); const publicRoute = require("./routes/publicRoute"); const cookieParser = require("cookie-parser"); const privateRoute = require("./routes/privateRoute"); const path = require("path"); const app = express(); // 1. CORS中间件 app.use(function (req, res, next) { const allowedOrigins = process.env.ALLOWED_ORIGINS.split(","); const NODE_ENV = process.env.NODE_ENV; const origin = req.headers.origin; if (origin && allowedOrigins.includes(origin) ) { res.setHeader("Access-Control-Allow-Origin", origin); } res.setHeader( "Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS", ); res.setHeader( "Access-Control-Allow-Headers", "Content-Type,Authorisation,x-client-type,Accept", ); res.setHeader("Access-Control-Allow-Credentials", "true"); if (req.method === "OPTIONS") { return res.status(200).end(); } next(); }); // 2. 解析中间件 app.use(cookieParser()); app.use(express.json()); app.use(express.urlencoded({ extended: true })); // 3. 所有API路由 app.use("/user", publicRoute); // routes for Login,reset etc app.use("/private", privateRoute); // private routes for dashboard,profile etc app.get("/test", (req, res) => { res.json({ test: true }); }); // 4. 静态文件托管 + SPA兜底路由(必须放在最后) app.use(express.static(path.join(__dirname, "dist"))); app.get("*", (req, res) => { res.sendFile(path.join(__dirname, "dist", "index.html")); }); app.listen(3000, () => console.log("app started on port 3000"));
这样调整后,所有API请求会优先被对应的路由处理,只有当请求的是静态资源(比如React的JS/CSS文件)或者未匹配的前端路由(比如React Router里的页面路径)时,才会返回index.html,你的/test接口就能正常返回JSON了。
备注:内容来源于stack exchange,提问作者adithyan sivaraman
相关产品推荐
相关产品推荐

