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

POST请求报错Cannot POST /,疑路由参数写法问题求助

问题:提交表单报错Cannot POST /,POST路由支持带URL参数吗?

提交表单时始终报错Cannot POST / - URL with parameters,文章访问路径为/articles/title_of_article格式,怀疑问题出在POST路由的写法articlesRouter.post('articles/:target'.....),想确认POST方法是否无法使用带:params的路由。

相关代码

POST路由

articlesRouter.post('articles/:target', async (req, res) => {
    const target = req.params.target.replaceAll("_", " ")
    const article = await Article.findOne({where: {title: target}})
    if (article)
    {
        const author = req.body.commentAuthor
        const text = req.body.commentText
        await article.createComment({author, text})
        console.log("POST METHOD IS WORKING")
    }
})

表单代码

<form method="post">
    <textarea placeholder="Title of your article" id="title" name="articleTitle"></textarea>
    <br />
    <textarea placeholder="Body of your article" id="body" type="text" name="articleBody"></textarea>
    <br />
    <button id="submit" type="submit">Done</button>
</form>

GET路由

articlesRouter.get('/articles/:target', async (req, res) => {
    const target = req.params.target.replaceAll("_", " ")
    const searchResult = await Article.findOne({where: {title: target}})
    if (searchResult)
    {
        const correspondingComments = await searchResult.getComments()
        res.render('../views/currentArticle', {title: searchResult.title, text: searchResult.body, comments: correspondingComments})
    }
    else{
        console.log('Error')
    }
})

原因分析

  1. POST路由路径缺失开头斜杠:GET路由路径是'/articles/:target'(带开头斜杠),但POST路由写的是'articles/:target'(无开头斜杠),会导致路由路径拼接错误,无法匹配正确的POST请求。
  2. 表单未指定action属性:表单无action时默认提交到当前页面URL,但路由配置错误会让服务器找不到对应处理逻辑,返回Cannot POST /错误。另外表单字段名(articleTitle/articleBody)与路由读取的字段(commentAuthor/commentText)不匹配,即使路由匹配成功也无法获取正确数据。
  3. POST方法完全支持带URL参数的路由:你的怀疑不成立,Express中POST路由和GET路由一样可以使用URL参数,问题不在参数本身,而是路由和表单的配置错误。

解决方案

1. 修正POST路由路径

给POST路由路径加上开头斜杠,和GET路由保持一致:

articlesRouter.post('/articles/:target', async (req, res) => {
    const target = req.params.target.replaceAll("_", " ")
    const article = await Article.findOne({where: {title: target}})
    if (article) {
        const author = req.body.commentAuthor
        const text = req.body.commentText
        await article.createComment({author, text})
        console.log("POST METHOD IS WORKING")
        // 提交后重定向回文章页面,避免客户端重复提交
        res.redirect(`/articles/${req.params.target}`)
    } else {
        // 处理文章不存在的情况
        res.status(404).send("Article not found")
    }
})

2. 修正表单配置

  • 指定表单action属性为对应文章的POST路由(需在渲染页面时把文章slug传递给模板,比如title_of_article)
  • 修改表单字段名,与路由读取的字段保持一致:
<!-- 假设模板中可用变量articleSlug存储文章的slug -->
<form method="post" action="/articles/<%= articleSlug %>">
    <textarea placeholder="Your name" id="author" name="commentAuthor"></textarea>
    <br />
    <textarea placeholder="Your comment" id="comment" name="commentText"></textarea>
    <br />
    <button type="submit">Submit Comment</button>
</form>

3. 补充模板变量传递

在GET路由中,把文章slug(替换空格为下划线后的标题)传递给视图模板:

res.render('../views/currentArticle', {
    title: searchResult.title,
    text: searchResult.body,
    comments: correspondingComments,
    articleSlug: searchResult.title.replaceAll(" ", "_") // 传递slug变量
})

内容的提问来源于stack exchange,提问作者Dmitry

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 22:17:20