簡體   English   中英

在ajax調用中不存在必需的反偽造表單字段“ __RequestVerificationToken”

[英]The required anti-forgery form field “__RequestVerificationToken” is not present in ajax call

我在控制器中有以下方法

[HttpPost]
    [Authorize(Roles ="Klient")]
    [ValidateAntiForgeryToken]
    public ActionResult GetAvaiableHouses(DateTime startDate, DateTime endDate)
    {
        Session.Remove("Reservation");
        IEnumerable <SelectListItem> avaiableHouses = repository.GetAllNamesAvaiableHouses(repository.GetAvaiableHousesInTerm(startDate, endDate));

        List<string> houses = new List<string>();
        avaiableHouses.ToList().ForEach(item => houses.Add(item.Value));

        if(avaiableHouses.ToList().Count == 0)
        {
            return new EmptyResult();
        }

        Session["Reservation"] = new NewReservation()
        {
            StartDate = startDate,
            EndDate = endDate,
            AvaiableHouses = avaiableHouses
        };

        return PartialView("~/Views/Shared/_AvaiableHousesPartial.cshtml", houses);
        }

通過在View.cshtml中使用Ajax腳本來調用此方法

$(function () {
    $("#btnCheckAvaiableHouses").click(function () {

        $.ajax({
            type: "POST",
            url: "/ClientReservations/GetAvaiableHouses",
            data: '{startDate: "' + $("#startdate").val() + '",endDate:"' + $("#enddate").val() + '",__RequestVerificationToken:"' + $('input[name=__RequestVerificationToken]').val() +'"  }',
            contentType: "application/json; charset=utf-8",
            dataType: "text",
            success: function (response) {
                $('#avaiableHouses').html(response)
                if (!$('#avaiableHouses').is(':empty')) {
                    document.getElementById("btnConfirmTerm").style.visibility = 'visible';
                }
                else {
                    $('#avaiableHouses').html('Brak dostępnych domków w podanym terminie')
                }

            },
            failure: function (response) {
                alert(response.responseText);
            },
            error: function (response) {
                alert(response.responseText);
            }
        });
    });
});

這是帶有此按鈕的按鈕部分,稱為該腳本

<div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="button" id="btnCheckAvaiableHouses" value="Sprawdź dostępność domków" class="btn btn-default" /> 
                <input type="button" id="btnConfirmTerm" value="Potwierdź termin" onclick="location.href='@Url.Action("Create", "ClientReservations")'"  class="btn btn-default" style="visibility:hidden" />
            </div>
        </div>

我添加了附加參數

'",__RequestVerificationToken:"' + $('input[name=__RequestVerificationToken]').val() 

到ajax腳本中,但是在執行過程中我仍然收到錯誤

,__ RequestVerificationToken不存在。

可能是什么原因?

如果您對數據進行字符串化並使用contentType: 'application/json ,則將令牌添加到ajax標頭中,例如

var headers = { __RequestVerificationToken: $('input[name="__RequestVerificationToken"]').val() };

$.ajax({
    headers: headers,
    data: ... // remove the token from your existing implementation
    ....
});

然后您需要創建一個自定義FilterAttribute來從Headers中讀取值

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public sealed class ValidateHeaderAntiForgeryTokenAttribute : FilterAttribute, IAuthorizationFilter
{
    public void OnAuthorization(AuthorizationContext filterContext)
    {
        if (filterContext == null)
        {
            throw new ArgumentNullException("filterContext");
        }

        var httpContext = filterContext.HttpContext;
        var cookie = httpContext.Request.Cookies[AntiForgeryConfig.CookieName];
        AntiForgery.Validate(cookie != null ? cookie.Value : null, httpContext.Request.Headers["__RequestVerificationToken"]);
    }
}

在您的控制器方法中,將[ValidateAntiForgeryToken]替換為[ValidateHeaderAntiForgeryToken]

但是,不必對數據進行字符串化,可以使用

var data = {
    startDate: $("#startdate").val(),
    endDate: $("#enddate").val(),
    __RequestVerificationToken: $('input[name=__RequestVerificationToken]').val()
};

$.ajax({
    data: data,
    ....
});

並刪除contentType選項,使其使用默認的'application/x-www-form-urlencoded; charset=UTF-8' 'application/x-www-form-urlencoded; charset=UTF-8'

您尚未顯示表單,假設它包含@Html.AntiForgeryToken()@Html.TextBoxFor(m => m.startDate)@Html.TextBoxFor(m => m.endDate)以生成具有name="startDate"表單控件name="startDate"name="endDate" ,那么您可以簡單地使用

var data = $('form').serialize();

$.ajax({
    data: data,
    ....
});

序列化所有形式的控件,包括令牌

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM