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

Razor项目中Fetch/Ajax向API控制器提交数据异常问题求助

Razor Web项目表单提交问题修复

问题场景

搭建了一个Razor Web项目,配置了Antiforgery验证,定义了BookController、BookEntry实体类,编写了视图页面及对应的JavaScript提交逻辑,目前遇到两个问题:

  1. 点击Post Buton A(Fetch实现):能进入SimplePost方法,但entry参数为空
  2. 点击Post Buton B(Ajax实现):控制台报400错误,添加请求头后仍无法正常请求

修复Post Buton A(Fetch)的参数为空问题

问题根源

  • 使用serialize()生成的表单字符串,结合手动设置的contentType,会导致模型绑定无法正确解析参数
  • 未携带Antiforgery Token,不符合验证要求

修复代码

$("#search__btn").click(function (e) {
    // 阻止按钮默认行为
    e.preventDefault();
    // 创建FormData对象,自动处理表单数据格式
    var formData = new FormData($("#bookform")[0]);
    // 添加Antiforgery Token到表单数据中
    formData.append("__RequestVerificationToken", $('input:hidden[name="__RequestVerificationToken"]').val());
    
    fetch(url, {
        method: "POST",
        body: formData
    })
    .then(response => {
        console.log("done");
        return response.json();
    })
    .catch(err => console.error(err));
});

关键说明

  • 使用FormData替代serialize():浏览器会自动设置正确的Content-Type(包含边界符),确保模型绑定能解析参数
  • 手动添加Antiforgery Token到FormData:匹配[FromForm]的接收方式,同时满足验证要求
  • 添加e.preventDefault():避免按钮触发默认表单提交行为

修复Post Buton B(Ajax)的400错误问题

问题根源

  • 请求头设置与Program.cs中配置的Antiforgery HeaderName不匹配(配置的是XSRF-TOKEN,却额外添加了RequestVerificationToken)
  • 使用serialize()时未正确处理表单数据格式,或未正确传递Token

修复代码(FormData版本)

$("#search__btn2").click(function (e) {
    e.preventDefault();
    var formData2 = new FormData($("#bookform")[0]);
    
    $.ajax({
        url: url,
        type: "POST",
        beforeSend: function (xhr) {
            // 严格匹配Program.cs中配置的HeaderName
            xhr.setRequestHeader("XSRF-TOKEN", $('input:hidden[name="__RequestVerificationToken"]').val());
        },
        data: formData2,
        // 禁用jQuery自动处理数据和设置Content-Type,由浏览器自动处理
        processData: false,
        contentType: false,
        success: function (result, status, xhr) {
            console.log(`success`);
        },
        error: function (xhr, status, error) {
            console.log(`error: ${error}`);
        }
    }).always(function () {
        console.log(`always done`);
    });
});

可选修复(serialize版本)

如果坚持使用serialize(),需手动拼接Token并移除多余配置:

$("#search__btn2").click(function (e) {
    e.preventDefault();
    var formData2 = $("#bookform").serialize();
    // 拼接Antiforgery Token到表单参数中
    formData2 += "&__RequestVerificationToken=" + $('input:hidden[name="__RequestVerificationToken"]').val();
    
    $.ajax({
        url: url,
        type: "POST",
        beforeSend: function (xhr) {
            xhr.setRequestHeader("XSRF-TOKEN", $('input:hidden[name="__RequestVerificationToken"]').val());
        },
        data: formData2,
        success: function (result, status, xhr) {
            console.log(`success`);
        },
        error: function (xhr, status, error) {
            console.log(`error: ${error}`);
        }
    }).always(function () {
        console.log(`always done`);
    });
});

额外注意事项

  • 确保@Html.AntiForgeryToken()生成的隐藏输入框存在于页面中,且name属性为__RequestVerificationToken
  • API控制器结合Antiforgery时,需保证Token传递方式(请求头/表单参数)与配置一致
  • 所有提交按钮都要添加e.preventDefault(),避免触发默认表单提交导致页面刷新

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 11:05:47