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

JavaScript动态设置表单action的URL参数遇404错误排查

404 Not Found错误原因及解决方法

问题背景

我通过POST请求向服务器提交表单数据,用JavaScript动态创建表单元素并给action属性设置带URL参数的路径,但提交时出现404 Not Found错误。

前端代码

for(let i = 0; i < itemsDatabase.length; i++){
    document.getElementById("div-section-container").innerHTML += `
    <div class="div-results-container">
        <h2>${itemsDatabase[i].name}</h2>
        <img src=${itemsDatabase[i].image} class="img-result">
        <p>${itemsDatabase[i].desc}</p>  
        <form method="POST" action="/favorites/add/name/${itemsDatabase[i].name}/desc/${itemsDatabase[i].desc}/img/${itemsDatabase[i].image}/id/${itemsDatabase[i].id}">
        <button class="btn-favourite" type="submit">Mark As Favourite</Button>
    </div>
    `; 
}

服务器代码(Express)

app.post("/favorites/add/name/:name/desc/:desc/img/:img/id/:id", (req, res)=>{
  console.log(`Post request received`);
  console.log(req.params);
})

浏览器错误信息

Cannot POST /favorites/add/name/blue%20nightshade/desc/A%20plant%20that%20grows%20in%20the%20quieter%20areas%20of%20Hyrule.%20At%20night,%20it%20gives%20off%20a%20soft%20glow.%20Cook%20with%20it%20to%20increase%20your%20stealth./img/https://botw-compendium.herokuapp.com/api/v2/entry/blue_nightshade/image/id/198


问题根源

核心问题是URL路径参数里包含了斜杠/:你把图片的完整URL(比如https://xxx.com/xxx/image)直接放到了img路径参数中,这个URL本身的斜杠会彻底破坏后端路由的匹配规则。

后端定义的路由是/favorites/add/name/:name/desc/:desc/img/:img/id/:id,但实际请求中img参数是带斜杠的完整URL,导致路由被拆分成了/favorites/add/name/blue%20nightshade/desc/xxx/img/https://botw-compendium.herokuapp.com/api/v2/entry/blue_nightshade/image/id/198——这里img参数被截断成了https:,后面的//botw-compendium...变成了额外的路径段,完全不符合后端的路由定义,所以返回404。

另外还有两个小问题:

  • 前端动态拼接的HTML里,<form>标签没有闭合(缺少</form>),可能导致DOM结构混乱。
  • 把描述、图片URL这类含特殊字符(空格、斜杠等)的内容放到URL路径里,本身就容易引发编码、路由匹配问题,还会让URL冗长难维护。

解决方法

方案1:改用POST请求体传递数据(推荐)

把数据放到表单的隐藏输入框中,提交时通过请求体发送,而非拼到URL路径里:

修改后的前端代码

for(let i = 0; i < itemsDatabase.length; i++){
    document.getElementById("div-section-container").innerHTML += `
    <div class="div-results-container">
        <h2>${itemsDatabase[i].name}</h2>
        <img src="${itemsDatabase[i].image}" class="img-result">
        <p>${itemsDatabase[i].desc}</p>  
        <form method="POST" action="/favorites/add">
            <input type="hidden" name="name" value="${itemsDatabase[i].name}">
            <input type="hidden" name="desc" value="${itemsDatabase[i].desc}">
            <input type="hidden" name="img" value="${itemsDatabase[i].image}">
            <input type="hidden" name="id" value="${itemsDatabase[i].id}">
            <button class="btn-favourite" type="submit">Mark As Favourite</button>
        </form>
    </div>
    `; 
}

修改后的后端代码

// 先确保配置了Express的body解析中间件
app.use(express.urlencoded({ extended: true }));
app.use(express.json());

app.post("/favorites/add", (req, res)=>{
  console.log(`Post request received`);
  console.log(req.body); // 从请求体获取表单数据
  res.sendStatus(200); // 返回成功状态码
})

方案2:对路径参数进行URL编码(不推荐)

如果一定要用路径参数,需要对包含特殊字符的参数进行URL编码,前端用encodeURIComponent()处理:

// 修改action属性的拼接逻辑
action="/favorites/add/name/${encodeURIComponent(itemsDatabase[i].name)}/desc/${encodeURIComponent(itemsDatabase[i].desc)}/img/${encodeURIComponent(itemsDatabase[i].image)}/id/${itemsDatabase[i].id}"

后端不需要修改(Express会自动解码req.params),但这种方式依然存在URL过长、特殊字符处理不全的风险,还是优先推荐方案1。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 23:40:42