前端使用 fetch 发起 POST 请求,但后端仅注册了 GET 路由,导致 404;核心原因是路由方法(GET/POST)不一致,且存在脚本缓存干扰。
前端使用 `fetch` 发起 post 请求,但后端仅注册了 get 路由,导致 404;核心原因是路由方法(get/post)不一致,且存在脚本缓存干扰。
在开发基于 Express 的后端与 React/Vanilla JS 前端的 JWT 认证流程时,一个常见却极易被忽略的问题是:HTTP 请求方法(method)与服务端路由处理器类型不匹配。你代码中前端明确发送的是 POST 请求:
const res = await fetch("http://localhost:8080/api/verify", {
method: "POST", // ? 明确声明为 POST
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ email, password }),
});而后端却错误地定义为 app.get():
// ❌ 错误:客户端发 POST,服务端只监听 GET
app.get("/api/verify", (req, res) => { ... });这直接导致 Express 无法匹配到任何处理函数,返回标准的 404 Not Found 响应(正如控制台所见:POST http://localhost:8080/api/verify 404 (Not Found))。
✅ 正确做法是:前后端方法严格一致。既然前端用 POST 提交凭证,后端必须用 app.post() 注册路由:
// ✅ 修正:使用 app.post() 匹配 POST 请求
app.post("/api/verify", (req, res) => {
console.log("verify route called");
// 注意:需确保已配置 body 解析中间件(否则 req.body 为空)
// 在 app.js 中添加:
// app.use(express.json()); // 解析 application/json
// app.use(express.urlencoded({ extended: true })); // 解析表单数据
if (!req.body || !req.body.email || !req.body.password) {
return res.status(400).json({ error: "Email and password are required" });
}
const { email, password } = req.body;
const token = jwt.sign(
{ username: email, admin: email === "admin" && password === "admin" },
KEY
);
res.json({ token }); // ✅ 统一返回 JSON 格式
});⚠️ 同时注意两个关键配套项:
-
启用请求体解析中间件(常被遗漏)
Express 默认不解析 req.body。务必在路由注册前添加:app.use(express.json()); // 处理 JSON 请求体 app.use(express.urlencoded({ extended: true })); // 处理 x-www-form-urlencoded -
清除浏览器脚本缓存
即使修正了后端代码,若前端 JS 文件(如 signup.js)被浏览器缓存,旧逻辑仍会执行。开发时建议:- 打开 DevTools → Network 标签页 → 勾选 Disable cache;
- 或强制刷新(Ctrl+Shift+R / Cmd+Shift+R);
- 检查 Sources 面板确认加载的是最新版本脚本。
此外,原始前端代码中存在一个潜在逻辑错误:.then() 链与 async/await 混用,且 response.json() 未 await,会导致 response 变成 Promise 而非解析后的对象。推荐统一使用 await 写法,提升可读性与健壮性:
const handleSubmit = async (e) => {
e.preventDefault();
try {
const response = await fetch("http://localhost:8080/api/verify", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ email, password }),
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json(); // ✅ await 解析 JSON
const { token } = data;
if (token) {
const decoded = jwt.decode(token);
setMessage(`Welcome admin with token of ${decoded.username}`);
console.log("Success:", decoded);
} else {
setMessage("Something went wrong");
}
} catch (error) {
console.error("Authentication failed:", error);
setMessage("Login failed. Please check credentials.");
}
};总结:解决 Fetch 404 的三步检查清单:
? ① 确认前端 fetch 的 method 与后端 app.XXX() 路由方法完全一致(POST ↔ app.post);
? ② 确保 Express 已正确配置 express.json() 和 express.urlencoded() 中间件;
? ③ 开发阶段禁用浏览器缓存,避免运行过期 JS 逻辑。
完成以上修正后,/api/verify 将正常响应,JWT 流程即可打通。

















