Razor项目中Fetch/Ajax向API控制器提交数据异常问题求助
Razor Web项目表单提交问题修复
问题场景
搭建了一个Razor Web项目,配置了Antiforgery验证,定义了BookController、BookEntry实体类,编写了视图页面及对应的JavaScript提交逻辑,目前遇到两个问题:
- 点击Post Buton A(Fetch实现):能进入
SimplePost方法,但entry参数为空 - 点击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
相关产品推荐
相关产品推荐

