27

I have problem with below details from MVC project.

When I am trying to use jquery ajax request with loading panel like spinning gif (or even text), I am getting error, observed from fiddler that

The required anti-forgery form field "__RequestVerificationToken" is not present.

If I comment [ValidateAntiForgeryToken] attribute at POST action method and use loading panel it is working fine.I want to know why I am getting this error.

I have even used the query string serialized with

__RequestVerificationToken= $('input[name="__RequestVerificationToken"').val()

still I am getting error

The anti-forgery token could not be decrypted. If this application is hosted by a Web Farm or cluster, ensure that all machines are running the same version of ASP.NET Web Pages and that the <machineKey> configuration specifies explicit encryption and validation keys.

AutoGenerate cannot be used in a cluster

What should I use?

Here it updated question code

var token = $('input[name="__RequestVerificationToken"]').val();
$('#submitaddress').click(function subaddr(event) {
    event.preventDefault();
    event.stopPropagation();
  //$('#addAddress').html('<img src="/img/animated-overlay.gif"> Sending...');
   // $('#addAddress').blur();
    //  $(this).bl
    if ($('#Jobid').val()!="") {
        $('#TransportJobId').val(parseInt($('#Jobid').val()));
        $.ajax(
              {
                  url: '/TransportJobAddress/create',
                  type: 'POST',
                  data: "__RequestVerificationToken=" + token + "" + $('form[action="/TransportJobAddress/Create"]').serialize(),
                  success: function poste(data, textStatus, jqXHR) { $('#addAddress').html(data); return false; },
                  error: function err(jqXHR, textStatus, errorThrown) { alert('error at address :' + errorThrown); }
              });
    }
    else {
        var transportid = 2;
        $.ajax({
            url: '/TransportJob/create',
            type: 'POST',
            data: "__RequestVerificationToken=" + token + "" + $('form[action="/TransportJob/Create"]').serialize(),
            success: function sfn(data, textStatus, jqXHR) {
                transportid = parseInt(data);
                $('#Jobid').val(data);
               // alert('inserted id :' + data);
                $('#TransportJobId').val((transportid));
                $.ajax(
         {

             url: '/TransportJobAddress/create',
             type: 'POST',
             //beforeSend: function myintserver(xhr){  
             //        $('#addAddress').html('<div id="temp_load" style="text-align:center">please wait ...</div>');
             //}, 
             data: "__RequestVerificationToken=" + token + "" + $('form[action="/TransportJobAddress/Create"]').serialize(),
             success: function poste(data, textStatus, jqXHR) {
                 $('#addAddress').html(data);

             },
             error: function err(jqXHR, textStatus, errorThrown) {
                 alert('error at address :' + errorThrown);
             }

         });
            },
            error: function myfunction(jqXHR, textStatus, errorThrown) {
                alert("error at transport :" + jqXHR.textStatus);
            },
            complete: function completefunc() {
              //  alert('ajax completed all requests');
                return false;
            }

        });
    }
});

form tags

<form action="/TransportJob/Create" method="post"><input     name="__RequestVerificationToken" type="hidden"   value="ydYSei0_RfyBf619dQrhDwwoCM7OwWkJQQEMNvNdAkefiFfYvRQ0MJYYu0zkktNxlJk_y1ZJO9-yb-  COap8mqd0cvh8cDYYik4HJ0pZXTgE1" />   

TransportJob form tag 2 on same page

<form action="/TransportJobAddress/Create" method="post" novalidate="novalidate"><input name="__RequestVerificationToken" type="hidden"    value="Np2vUZJPk1TJlv846oPSU6hg4SjMHRcCk1CacaqZbpHOg8WbV4GZv06noRDl7F_iT9qQf3BIXo3n9wGW68sU mki7g3-ku_BSHBDN-g2aaKc1"> 

4

5 回答 5

37

我通常不会手动将其添加到每个请求中,而是执行以下操作:

var token = $('input[name="__RequestVerificationToken"]').val();
$.ajaxPrefilter(function (options, originalOptions) {
  if (options.type.toUpperCase() == "POST") {
    options.data = $.param($.extend(originalOptions.data, { __RequestVerificationToken: token }));
  }
});

这将自动将您的令牌添加到您执行的任何ajax POST 中。

于 2013-11-05T12:46:51.903 回答
18

您是否已将令牌添加到 ajax 调用的标头中?

您需要在 ajax 调用的消息头中添加 AntiForgeryToken:

var token = $('input[name="__RequestVerificationToken"]').val();

var headers = {};

headers['__RequestVerificationToken'] = token;

$.ajax({
        url: ... some url,
        headers: headers,
        ....
});

在你的代码中试试这个:

var token = $('input[name="__RequestVerificationToken"]').val();
var tokenadr = $('form[action="/TransportJobAddress/Create"] input[name="__RequestVerificationToken"]').val(); 

var headers = {};
var headersadr = {};
headers['__RequestVerificationToken'] = token;
headersadr['__RequestVerificationToken'] = tokenadr;

$('#submitaddress').click(function subaddr(event) {
    event.preventDefault();
    event.stopPropagation();
  //$('#addAddress').html('<img src="/img/animated-overlay.gif"> Sending...');
   // $('#addAddress').blur();
    //  $(this).bl
    if ($('#Jobid').val()!="") {
        $('#TransportJobId').val(parseInt($('#Jobid').val()));
        $.ajax(
              {
                  url: '/TransportJobAddress/create',
                  type: 'POST',
                  headers:headersadr, 
                  data: "__RequestVerificationToken=" + token + "" + $('form[action="/TransportJobAddress/Create"]').serialize(),
                  success: function poste(data, textStatus, jqXHR) { $('#addAddress').html(data); return false; },
                  error: function err(jqXHR, textStatus, errorThrown) { alert('error at address :' + errorThrown); }
              });
    }
    else {
        var transportid = 2;
        $.ajax({
            url: '/TransportJob/create',
            type: 'POST',
            headers:headers, 
            data: $('form[action="/TransportJob/Create"]').serialize(),
            success: function sfn(data, textStatus, jqXHR) {
                transportid = parseInt(data);
                $('#Jobid').val(data);
               // alert('inserted id :' + data);
                $('#TransportJobId').val((transportid));
                $.ajax(
         {

             url: '/TransportJobAddress/create',
             type: 'POST',
             //beforeSend: function myintserver(xhr){  
             //        $('#addAddress').html('<div id="temp_load" style="text-align:center">please wait ...</div>');
             //},
             headers:headers, 
             data: $('form[action="/TransportJobAddress/Create"]').serialize(),
             success: function poste(data, textStatus, jqXHR) {
                 $('#addAddress').html(data);

             },
             error: function err(jqXHR, textStatus, errorThrown) {
                 alert('error at address :' + errorThrown);
             }

         });
            },
            error: function myfunction(jqXHR, textStatus, errorThrown) {
                alert("error at transport :" + jqXHR.textStatus);
            },
            complete: function completefunc() {
              //  alert('ajax completed all requests');
                return false;
            }

        });
    }
});

在您的 ajax 调用中添加了标题行。

于 2013-11-05T12:42:28.147 回答
3

您是否已将令牌添加到您的视图中?像这样:

<form method="post" action="/my-controller/my-action">
    @Html.AntiForgeryToken()
</form>

由于接收帖子的控制器正在寻找防伪令牌,因此您需要确保将其添加到视图中的表单中。

编辑:

首先尝试在 json 中构建数据:

var formData = $('form[action="/TransportJobAddress/Create"]').serialize();
$.extend(formData, {'__RequestVerificationToken': token });

//and then in your ajax call:
$.ajax({
    //...
    data:formData
    //...
});
于 2013-11-05T12:28:49.773 回答
2

视图或布局:

<form id='_id' method='POST'> @html.antiforgeryToken(); </form>

ajax调用函数

var data={...};
var token=$('#_id').serializeObject();
var dataWithAntiforgeryToken = $.extend(data,token);

$.ajax(
{
....,
data: dataWithAntiforgeryToken;
}
)
于 2015-06-17T13:13:26.703 回答
0

我想保护 Ajax 和正常请求,所以这就是我想出来的:

首先使用来自 haacked.com的优秀博客,我按照描述创建了 ConditionalFilterProvider。

然后我按照codethinked的博客中的描述创建了所有类。

在我的 _layout 页面上,我按照博客中的描述添加了带有 $.ajaxPrefilter 的片段...这确保了我所有的 Ajax 回调现在都通过标头发送 Antiforgery 令牌。

为了将所有内容粘合在一起,我在 global.asax / Application_Start 上添加了这段代码

(c, a) =>
                    (c.HttpContext.Request.IsAjaxRequest() &&
                     !string.Equals(c.HttpContext.Request.HttpMethod, "GET"))
                        ? new AjaxValidateAntiForgeryTokenAttribute()
                        : null,
(c, a) =>
                    (!c.HttpContext.Request.IsAjaxRequest() &&
                     string.Equals(c.HttpContext.Request.HttpMethod, "POST", StringComparison.OrdinalIgnoreCase))
                        ? new ValidateAntiForgeryTokenAttribute()
                        : null

基本上.. 将属性注入到我所有不是 GET 的控制器中。

之后我只需要去我所有的(很少)表格并添加@Html.AntiForgeryToken()。

为了证明一切正常,我只是尝试使用没有 AntiForgeryToken 的表单来填充事物并获得预期的异常。并删除 $.ajaxPrefilter 并创建 Ajax 请求并收到预期的异常。

于 2014-01-09T10:17:57.223 回答