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

ASP.NET Core MVC中通过AJAX发送AntiForgeryToken的正确方式

问题分析与修正方案

原代码核心缺陷

  • 冗余表单令牌:顶部Html.BeginForm生成的令牌未被使用,属于无效代码。
  • 令牌API调用错误:AntiForgery.GetTokens是旧版API,ASP.NET Core中需注入IAntiforgery服务调用,直接静态调用会报“当前上下文不存在该方法”。
  • DOM取值错误:用innerText获取input值,正确方式是读取value属性。
  • JavaScript语法错误:realdata对象用分号分隔属性,AJAX的headers未用对象格式包裹。
  • 未阻止表单默认提交:点击submit会同时触发普通POST和AJAX请求,页面刷新会中断AJAX。
  • 令牌选择器错误:getFormToken中的选择器多了冗余反引号,无法正确匹配令牌元素。

正确实现方式(兼容默认[ValidateAntiForgeryToken])

ASP.NET Core的[ValidateAntiForgeryToken]默认支持两种验证逻辑:

  1. 表单数据中包含__RequestVerificationToken字段
  2. 请求头携带RequestVerificationToken,同时浏览器自动发送对应防伪Cookie(同域请求默认携带)

推荐用请求头方式,更简洁且不污染表单数据,具体实现如下:

步骤1:注入并获取防伪令牌

在视图中注入IAntiforgery服务,生成合法令牌:

@inject IAntiforgery Antiforgery
@{
    var tokenSet = Antiforgery.GetAndStoreTokens(Context);
    var requestToken = tokenSet.RequestToken;
}

步骤2:修正JavaScript逻辑

  • 阻止表单默认提交行为
  • 正确读取输入值
  • 在AJAX请求头中携带令牌
  • 修复语法错误

步骤3:清理冗余代码

移除无用的Html.BeginForm块,保留必要的令牌生成逻辑。

修正后的完整代码

Razor视图代码

@{
    ViewData["Title"] = "Kiosk";
}
@model YourNamespace.CodeModel
@inject IAntiforgery Antiforgery

@{
    // 自动生成并存储防伪Cookie,同时获取请求令牌
    var tokenSet = Antiforgery.GetAndStoreTokens(Context);
}

<h1>Check-in Kiosk</h1>
<title>@ViewData["Title"]</title>

<h2>Follow the instructions below.</h2>

<p id="instructions" style="color: green;">
    Slide your ID card into the card-holder and wait for further instructions.
</p>

<div id="row">
    <div class="col-md-4">
        <form method="post" onsubmit="getData(event)">
            <div asp-validation-summary="All" class="text-danger pb-2" id="errors"></div>
            
            <div class="form-floating pb-2">
                <input asp-for="ScannedCode" class="form-control" id="scancode"/>
                <label asp-for="ScannedCode"></label>
                <span asp-validation-for="ScannedCode" class="text-danger"></span>
            </div>

            <div class="form-floating pb-2">
                <input asp-for="Number" class="form-control" id="number"/>
                <label asp-for="Number"></label>
                <span asp-validation-for="Number" class="text-danger"></span>
            </div>

            <div class="form-group pt-4">
                <input type="submit" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script>
    function getData(event) {
        // 阻止表单默认提交,避免页面刷新
        event.preventDefault();
        
        let scannedCode = document.getElementById("scancode").value;
        let number = document.getElementById("number").value;

        sendData(scannedCode, number);
    }

    function sendData(scannedCode, number) {
        let realdata = { 
            ScannedCode: scannedCode,
            Number: number
        };
        
        $.ajax({
            type: "POST",
            url: "@Url.Action("Index", "Kiosk")",
            data: realdata,
            dataType: 'json',
            headers: {
                'RequestVerificationToken': '@tokenSet.RequestToken'
            },
            success: function (response) {
                document.getElementById("instructions").innerText = response.message;
                
                setTimeout(function () {
                    location.reload();
                }, response.seconds);
            },
            error: function() {
                document.getElementById("instructions").innerText = "请求失败,请重试";
            }
        });
    }
</script>

后端代码(无需修改)

[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Index([Bind("ScannedCode,Number")] CodeModel input) {
    // 业务逻辑实现
}

关键说明

  • IAntiforgery.GetAndStoreTokens(Context)会自动生成并设置防伪Cookie(.AspNetCore.Antiforgery.xxx),浏览器同域请求时会自动携带该Cookie。
  • AJAX只需在请求头中携带RequestVerificationToken,[ValidateAntiForgeryToken]会自动验证Cookie与请求令牌的匹配性。
  • 若偏好表单字段方式,可在realdata中添加__RequestVerificationToken: '@tokenSet.RequestToken',无需设置请求头,验证效果一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 19:43:15