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

发起POST请求时event.preventDefault()失效,页面仍刷新如何解决?

问题描述

我尝试提交表单向json-server发送POST请求并在页面展示数据,为避免每次提交时页面刷新,在submit事件的第一行添加了event.preventDefault()。POST请求成功,表单数据已成功存入json-server,但提交时页面始终会刷新。我确定问题与POST请求有关,因为注释掉POST请求、添加console.log("form submitted")后提交表单,页面不会刷新且控制台能看到对应消息,但恢复POST请求后页面又会刷新。

相关代码片段

function monsterSubmit() {
    const monsterForm = document.getElementById("monster-form");
    monsterForm.addEventListener("submit", event => {
        event.preventDefault();

        const monsterObj = {
            name: event.target[0].value,
            age: event.target[1].value,
            description: event.target[2].value
        }

        fetch("http://localhost:3000/monsters", {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
                Accept: "application/json" 
            },
            body: JSON.stringify(monsterObj)
        })
            .then(res => res.json())
            .then(monster => console.log(monster))
            .catch(err => console.log(err))

    })
}

完整JS文件代码

document.addEventListener("DOMContentLoaded", () => {
    getMonsters();
    monsterSubmit();
})

function getMonsters() {
    const monsterContainer = document.getElementById("monster-container");
    fetch("http://localhost:3000/monsters?_limit=50")
        .then(res => res.json())
        .then(monsters => {
            monsters.forEach(monster => {
                const monsterName = document.createElement("h2");
                const monsterAge = document.createElement("h4");
                const monsterBio = document.createElement("p");
                const monsterInfo = document.createElement("div");

                monsterName.textContent = monster.name;
                monsterAge.textContent = `Age: ${monster.age}`;
                monsterBio.textContent = `Bio: ${monster.description}`;

                monsterInfo.append(monsterName, monsterAge, monsterBio);

                monsterContainer.appendChild(monsterInfo);
            })
        })
        .catch(err => console.error(err))
}

function monsterSubmit() {
    const monsterForm = document.getElementById("monster-form");
    monsterForm.addEventListener("submit", event => {
        event.preventDefault();

        const monsterObj = {
            name: event.target[0].value,
            age: event.target[1].value,
            description: event.target[2].value
        }

        fetch("http://localhost:3000/monsters", {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
                Accept: "application/json" 
            },
            body: JSON.stringify(monsterObj)
        })
            .then(res => res.json())
            .then(monster => console.log(monster))
            .catch(err => console.log(err))

    })
}
解决方案

1. 检查HTML表单属性

确认表单标签没有设置action属性,也没有通过onsubmit绑定其他提交逻辑——如果存在这些属性,可能会绕过event.preventDefault()触发默认提交刷新。

2. 补充阻止事件冒泡

在event.preventDefault()后添加event.stopPropagation(),防止事件冒泡引发的意外默认行为:

monsterForm.addEventListener("submit", event => {
    event.preventDefault();
    event.stopPropagation(); // 新增这一行

    // 剩余代码不变
})

3. 排查响应解析错误

虽然POST请求成功,但如果json-server返回的响应不是合法JSON,res.json()会抛出异常,可能导致浏览器出现意外行为。可以临时修改fetch的响应处理逻辑,排查问题:

fetch("http://localhost:3000/monsters", {
    method: "POST",
    headers: {
        "Content-Type": "application/json",
        Accept: "application/json" 
    },
    body: JSON.stringify(monsterObj)
})
.then(res => {
    console.log("响应状态码:", res.status);
    return res.text(); // 先获取文本而非直接解析JSON
})
.then(text => {
    console.log("响应内容:", text);
    try {
        const monster = JSON.parse(text);
        console.log("解析后的怪物数据:", monster);
    } catch (err) {
        console.error("JSON解析失败:", err);
    }
})
.catch(err => console.error("请求错误:", err))

4. 确保事件只绑定一次

在monsterSubmit函数开头添加日志,确认该函数只执行一次(避免重复绑定submit事件导致冲突):

function monsterSubmit() {
    console.log("绑定submit事件"); // 新增日志
    const monsterForm = document.getElementById("monster-form");
    // 剩余代码不变
}

如果控制台多次打印这句话,说明函数被重复调用,需要排查调用时机。

额外优化建议

不要通过索引event.target[0]获取表单元素,给表单控件添加name属性后通过名称取值,代码更稳定:

<!-- HTML表单示例 -->
<form id="monster-form">
    <input type="text" name="name" placeholder="怪物名称">
    <input type="number" name="age" placeholder="年龄">
    <textarea name="description" placeholder="描述"></textarea>
    <button type="submit">添加怪物</button>
</form>
// JS中取值
const monsterObj = {
    name: event.target.name.value,
    age: event.target.age.value,
    description: event.target.description.value
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 06:15:00