jQuery 如何在mvc中使用防伪令牌发出ajax请求
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19788916/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to make ajax request with anti-forgery token in mvc
提问by Ravi Hanok
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.
如果我[ValidateAntiForgeryToken] attribute
在 POST 操作方法中发表评论
并使用加载面板,它就可以正常工作。我想知道为什么会出现此错误。
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">
采纳答案by freshbm
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 调用中添加了标题行。
回答by Kippie
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 anyajax POST you do.
这将自动将您的令牌添加到您执行的任何ajax POST。
回答by hofnarwillie
Have you added the token to your 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
//...
});
回答by Ashish Kumar Sharma
View or Layout:
视图或布局:
< form id='_id' method='POST'> @html.antiforgeryToken(); < /form>
<form id='_id' method='POST'> @html.antiforgeryToken(); </form>
The ajax call function:
ajax调用函数:
var data={...};
var token=$('#_id').serializeObject();
var dataWithAntiforgeryToken = $.extend(data,token);
$.ajax(
{
....,
data: dataWithAntiforgeryToken;
}
)
回答by CodeHacker
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.comI 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. And remove the $.ajaxPrefilter and create Ajax requests and the expected exception was received.
为了证明一切正常,我只是尝试使用没有 AntiForgeryToken 的表单来填充内容并获得预期的异常。并删除 $.ajaxPrefilter 并创建 Ajax 请求并收到预期的异常。