You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用ExpressJS和CSRF时无法发起POST请求的问题排查

排查"Cannot POST /process"错误的关键问题

让我帮你梳理下代码里的两个核心问题,这就是导致错误的根源:

1. 表单提交路径不匹配

你的routesAPI路由器在index.js里是挂载在/api前缀下的:

app.use("/api", routesAPI);

而routes-api.js里的POST路由是/process,所以这个接口的实际完整路径是/api/process,但你表单里写的action是/process,浏览器直接请求根路径下的/process,但这个路由根本不存在,所以触发了"Cannot POST /process"的错误。

解决办法:
修改send.html里的表单action:

<form action="/api/process" method="POST">

2. 静态文件无法渲染模板变量

你用res.sendFile()发送send.html,但这个方法只是把文件原封不动返回给浏览器,不会解析里面的{{csrfToken}}模板变量。所以表单里的_csrf字段值其实是字符串{{csrfToken}},不是真实的CSRF令牌——就算路径改对了,后续也会触发CSRF验证失败。

解决办法:
有两种方式处理这个问题:

方式一:直接生成HTML字符串返回

如果不想用模板引擎,可以在路由里直接拼接HTML,把CSRF令牌嵌入进去:

router.get("/", csrfProtection, (req, res) => {
  console.log("crsf: " + req.csrfToken());
  const formHtml = `
    <form action="/api/process" method="POST">
      <input type="text" name="_csrf" value="${req.csrfToken()}">
      Favorite color: <input type="text" name="favoriteColor">
      <button type="submit">Submit</button>
    </form>
  `;
  res.send(formHtml);
});

方式二:使用模板引擎(更推荐)

如果后续页面复杂,建议用模板引擎来渲染页面,比如EJS:

  1. 先安装EJS依赖:
npm install ejs
  1. 在index.js里配置模板引擎:
const path = require('path');
// ... 其他代码
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views')); // 新建一个views文件夹存放模板文件
  1. 把send.html改名为send.ejs,放到views文件夹里,内容保持不变;
  2. 修改routes-api.js里的GET路由,用res.render()渲染模板:
router.get("/", csrfProtection, (req, res) => {
  console.log("crsf: " + req.csrfToken());
  res.render('send', { csrfToken: req.csrfToken() });
});

做完这两步修改后,重新启动服务器,表单就能正确提交到/api/process,并且CSRF令牌也能正确传递了。

内容的提问来源于stack exchange,提问作者José Carlos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:26:18