简体   繁体   English

如何在mvc中使用防伪令牌制作ajax请求

[英]How to make ajax request with anti-forgery token in mvc

I have problem with below details from MVC project. 我对MVC项目的以下细节有疑问。

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 当我试图使用jquery ajax请求加载面板像旋转gif(甚至文本)时,我收到错误,从提琴手观察到

The required anti-forgery form field "__RequestVerificationToken" is not present. 所需的防伪表单字段“__RequestVerificationToken”不存在。

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. 如果我在POST操作方法中注释[ValidateAntiForgeryToken] attribute并使用加载面板它工作正常。我想知道为什么我收到此错误。

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. 如果此应用程序由Web场或群集托管,请确保所有计算机都运行相同版本的ASP.NET网页,并且<machineKey>配置指定显式​​加密和验证密钥。

AutoGenerate cannot be used in a cluster AutoGenerate不能在群集中使用

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 TransportJob表单标记2在同一页面上

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

Rather than manually adding it to each request, I usually do something like this: 我不是手动将其添加到每个请求中,而是通常执行以下操作:

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

This will automatically add your token to any ajax POST you do. 这会自动将您的令牌添加到您执行的任何 ajax POST。

Have you added your token to the header of the ajax call? 您是否已将令牌添加到ajax调用的标头中?

You need to add AntiForgeryToken in your message header in the ajax call: 您需要在ajax调用的消息头中添加AntiForgeryToken:

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

var headers = {};

headers['__RequestVerificationToken'] = token;

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

Try this in your code: 在您的代码中尝试此操作:

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;
            }

        });
    }
});

Added headers line in your ajax call. 在ajax调用中添加了标题行。

Have you added the token to your View? 您是否已将令牌添加到View中? Like this: 像这样:

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

Since your controller receiving the post is looking for the anti forgery token, you need to ensure that you add it to your form in the view. 由于接收帖子的控制器正在寻找防伪令牌,因此您需要确保将其添加到视图中的表单中。

EDIT: 编辑:

Try building your data in json first: 首先尝试在json中构建数据:

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

//and then in your ajax call:
$.ajax({
    //...
    data:formData
    //...
});

View or Layout: 查看或布局:

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

The ajax call function : ajax调用函数

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

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

I wanted to secure both Ajax and normal request, so here is what I came out with: 我想保护Ajax和普通请求,所以这就是我提出的:

First using the excellent blog from haacked.com I Created the ConditionalFilterProvider as described. 首先使用来自haacked.com的优秀博客我按照描述创建了ConditionalFilterProvider。

Then I created all the classes as described on the blog from codethinked . 然后我创建了所有类,如博客中所描述的codethinked

On my _layout page I added the piece with the $.ajaxPrefilter as described in the blog... This assures that all my Ajax-callback now send the Antiforgery token through header. 在我的_layout页面上,我添加了一个带有$ .ajaxPrefilter的文章,如博客中所述...这确保我所有的Ajax回调现在都通过标题发送Antiforgery令牌。

To glue all together I added this piece of code on my global.asax / Application_Start 为了将所有内容粘合在一起,我在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

Basically.. inject the attribute to all my Controllers that are not GET. 基本上..将属性注入我不是GET的所有控制器。

After that I just had to go to all my (Very few) forms and add the @Html.AntiForgeryToken(). 之后,我只需要访问所有(极少数)表单并添加@ Html.AntiForgeryToken()。

To proof that all worked I just try to dens things with a form without the AntiForgeryToken and get the expected exception. 为了证明一切正常,我只是尝试使用没有AntiForgeryToken的表单来确定事物,并获得预期的异常。 And remove the $.ajaxPrefilter and create Ajax requests and the expected exception was received. 并删除$ .ajaxPrefilter并创建Ajax请求并收到预期的异常。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用防伪令牌将JSON模型发布到ASP.Net MVC3 - Posting a JSON model to ASP.Net MVC3 with Anti-forgery token 使用CORS预检OPTIONS请求的Ajax防伪POST(302重定向) - Ajax anti-forgery POST with CORS preflight OPTIONS request (302 redirect) 在ajax调用中不存在必需的反伪造表单字段“ __RequestVerificationToken” - The required anti-forgery form field “__RequestVerificationToken” is not present in ajax call 如何使用Ajax文件上传发送防伪标记? - How to send anti forgery token with Ajax file upload? MVC 5多个防伪令牌AJAX - MVC 5 Multiple Anti Forgery tokens AJAX 所需的防伪 cookie“__RequestVerificationToken”不存在 - The required anti-forgery cookie "__RequestVerificationToken" is not present 使用 JQuery 向表单添加元素会导致提交时出现“无法解密防伪令牌”错误 - Adding elements to a form using JQuery causes the “The anti-forgery token could not be decrypted” error on submit 从ajax方法调用操作将引发错误:所需的防伪表单字段“ __RequestVerificationToken”不存在 - Invoking action from ajax method is throwing an error: The required anti-forgery form field “__RequestVerificationToken” is not present 使用jQuery Ajax和Html.AntiForgeryToken()时,防伪表单字段“__RequestVerificationToken”不存在 - anti-forgery form field “__RequestVerificationToken” is not present when using jQuery Ajax and the Html.AntiForgeryToken() asp.net mvc“所需的防伪表单字段”__ RequestVerificationToken“不存在。” - asp.net mvc “The required anti-forgery form field”__RequestVerificationToken“ is not present.”
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM