我正在开发一个 .net 6 MVC Web 应用程序作为前端,并使用 .net 6 Web api 项目作为后端。
有一个函数可以进行 AJAX POST 调用来获取数据,并且它可以在请求中使用
@Html.AntiForgeryToken()
顺利运行。 Token与其他参数一起放在数据中。我的控制器中的断点已按预期触发。
视图:(很确定这是此视图中的唯一标记)
@Html.AntiForgeryToken()
Ajax:(这很好用)
function ProductSearch() {
var token = $(':input:hidden[name*="RequestVerificationToken"]');
$.ajax({
type: 'POST',
url: '@Url.Content("~/MyController/SearchProduct")',
data: {
__RequestVerificationToken: token.val(),
data: $('#data').val()
},
success: function (res) {
if (res.IsSuccess === false) {
Swal.fire({
icon: 'error',
title: res.Message,
showConfirmButton: true
})
}
else {
$("#divToBeReplaced").html('');
$("#divToBeReplaced").html(res);
}
},
error: function (xhr, textStatus, error) {
CloseLoading();
Swal.fire({
icon: 'error',
title: 'error',
showConfirmButton: true,
timer: 1500
})
}
})
}
控制器动作:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> SearchProduct(string? data)
{
...
}
但是,我正在处理的另一个 AJAX 请求(使用上面提到的相同的
@Html.AntiForgeryToken()
)无法发布到控制器,并立即收到 HTTP 400 错误。
与之前的AJAX类似,CSRF令牌被放置在AJAX数据中:
(尝试将其放入标题中,但仍然失败)
var token = $('input[name="__RequestVerificationToken"]').val();
$.ajax({
type: 'POST',
url: '@Url.Content("~/MyController/DeleteCheckedProduct")',
beforeSend: function (request) {
request.setRequestHeader('RequestVerificationToken', token);
},
data: {
__RequestVerificationToken: token,
delList: delList
},
...
控制器:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteCheckedProduct(string delList)
{
...
}
也许
Program.cs
设置的内容会影响我的 AJAX 帖子?
builder.Services.AddControllersWithViews(options =>
{
//options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute()); → commented
})
.AddJsonOptions(options =>
{
options.JsonSerializerOptions.PropertyNamingPolicy = null;
options.JsonSerializerOptions.NumberHandling = JsonNumberHandling.WriteAsString;
});
正如你所看到的,这似乎是一个简单的问题,两个Ajax功能几乎相同,我仍然无法弄清楚为什么第二个AJAX无法请求。任何线索将不胜感激,谢谢!
尝试在删除检查产品操作上发送不带
[ValidateAntiForgeryToken]
属性的发布请求,效果很好。
由于脚本在名为
RequestVerificationToken
的标头中发送令牌,因此在 Program.cs 中,配置防伪服务以查找 RequestVerificationToken
标头:
builder.Services.AddAntiforgery(o => o.HeaderName = "RequestVerificationToken");