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

Promise中then语句失效求助:表单提交后无输出且报错

问题:表单提交Promise异常,.then无输出、URL异常跳转

我在表单提交触发的函数里用了Promise。首次提交表单时控制台完全没输出,之后每次提交都会触发.catch返回错误信息,而且URL会从http://127.0.0.1:8000/变成http://127.0.0.1:8000/?。我怀疑是API请求路径变成了/?/emails而非/emails导致的问题?作为JavaScript新手,想知道为什么.then的控制台输出不生效,哪里操作错了?

现有代码

JavaScript代码

document.addEventListener('DOMContentLoaded', function () {

    ...

    // Submit email
    document.querySelector('#compose-form').addEventListener('submit', submitEmail)
});

function submitEmail() {
    fetch('/emails', {
        method: 'POST',
        body: JSON.stringify({
            recipients: 'person@example.com',
            subject: 'Hello',
            body: 'Hello, world!'
        })
    })
        .then(response => response.json())
        .then(result => {
            // Print result
            console.log(result); // this does not work
        })
        .catch(error => {
            console.log('Error: idk something happened', error); // the error message that is shown
            // the error parameter does not actually show anything either, just the string is shown on the console
        });
}

HTML代码

<form id="compose-form">
    <div class="form-group">
        From: <input disabled class="form-control" value="{{ request.user.email }}">
    </div>
    <div class="form-group">
        To: <input id="compose-recipients" class="form-control">
    </div>
    <div class="form-group">
        <input class="form-control" id="compose-subject" placeholder="Subject">
    </div>
    <textarea class="form-control" id="compose-body" placeholder="Body"></textarea>
    <input type="submit" class="btn btn-primary" id="submit-new" />
</form>

问题分析与解决

核心问题1:表单默认提交行为未阻止

表单点击提交按钮后,浏览器会执行默认同步提交行为——直接刷新页面并跳转,这会中断你发起的异步fetch请求:

  • 首次提交时,页面立刻刷新,fetch请求还没完成就被终止,所以控制台无输出;
  • 页面刷新后URL变成http://127.0.0.1:8000/?(表单默认是GET提交,未指定action和method时,会把空表单参数拼到URL后);
  • 后续提交时,页面刷新前fetch请求可能刚好触发中断错误,所以.catch执行,但error对象因请求中断没有有效信息。

核心问题2:fetch请求缺少必要请求头

你用JSON.stringify把请求体转成了JSON,但未设置Content-Type: application/json请求头,后端可能无法正确解析请求体,导致返回错误响应,这也会让.then无法正常执行(fetch仅在网络故障时触发.catch,后端返回4xx/5xx状态码不会自动抛出错误)。

修复步骤

  1. 阻止表单默认提交行为
    在submitEmail函数开头添加event.preventDefault(),阻止页面刷新:
function submitEmail(event) {
    // 阻止表单默认提交行为
    event.preventDefault();

    fetch('/emails', {
        method: 'POST',
        // 添加请求头,告知后端请求体为JSON格式
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            recipients: 'person@example.com',
            subject: 'Hello',
            body: 'Hello, world!'
        })
    })
        .then(response => {
            // 手动判断响应状态,非2xx状态抛出错误进入catch
            if (!response.ok) {
                throw new Error(`HTTP错误!状态码: ${response.status}`);
            }
            return response.json();
        })
        .then(result => {
            console.log(result); // 现在可以正常输出了
        })
        .catch(error => {
            console.log('错误: 发生了异常', error); // 现在能拿到具体错误信息
        });
}
  1. 添加JSON请求头
    在fetch配置对象中加入headers字段,确保后端能正确解析JSON请求体。

  2. 手动处理HTTP错误状态
    fetch不会因后端返回4xx/5xx状态码自动触发.catch,需在第一个.then中判断response.ok,手动抛出错误,让异常能被.catch捕获。

额外优化:使用表单实际输入值

目前代码硬编码了提交内容,可改为读取表单实际输入值:

function submitEmail(event) {
    event.preventDefault();

    // 获取表单输入值
    const recipients = document.querySelector('#compose-recipients').value;
    const subject = document.querySelector('#compose-subject').value;
    const body = document.querySelector('#compose-body').value;

    fetch('/emails', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            recipients,
            subject,
            body
        })
    })
        .then(response => {
            if (!response.ok) {
                throw new Error(`HTTP错误!状态码: ${response.status}`);
            }
            return response.json();
        })
        .then(result => {
            console.log(result);
            // 提交成功后重置表单
            document.querySelector('#compose-form').reset();
        })
        .catch(error => {
            console.error('提交失败:', error);
        });
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 13:10:29