[英]How to make ajax request with anti-forgery token in mvc
我對MVC項目的以下細節有疑問。
當我試圖使用jquery ajax請求加載面板像旋轉gif(甚至文本)時,我收到錯誤,從提琴手觀察到
所需的防偽表單字段“__RequestVerificationToken”不存在。
如果我在POST操作方法中注釋[ValidateAntiForgeryToken] attribute
並使用加載面板它工作正常。我想知道為什么我收到此錯誤。
我甚至使用了序列化的查詢字符串
__RequestVerificationToken= $('input[name="__RequestVerificationToken"').val()
我仍然得到錯誤
防偽令牌無法解密。 如果此應用程序由Web場或群集托管,請確保所有計算機都運行相同版本的ASP.NET網頁,並且
<machineKey>
配置指定顯式加密和驗證密鑰。
AutoGenerate不能在群集中使用
我該怎么用?
這里更新了問題代碼
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 action="/TransportJob/Create" method="post"><input name="__RequestVerificationToken" type="hidden" value="ydYSei0_RfyBf619dQrhDwwoCM7OwWkJQQEMNvNdAkefiFfYvRQ0MJYYu0zkktNxlJk_y1ZJO9-yb- COap8mqd0cvh8cDYYik4HJ0pZXTgE1" />
TransportJob表單標記2在同一頁面上
<form action="/TransportJobAddress/Create" method="post" novalidate="novalidate"><input name="__RequestVerificationToken" type="hidden" value="Np2vUZJPk1TJlv846oPSU6hg4SjMHRcCk1CacaqZbpHOg8WbV4GZv06noRDl7F_iT9qQf3BIXo3n9wGW68sU mki7g3-ku_BSHBDN-g2aaKc1">
我不是手動將其添加到每個請求中,而是通常執行以下操作:
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。
您是否已將令牌添加到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調用中添加了標題行。
您是否已將令牌添加到View中? 像這樣:
<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
//...
});
查看或布局:
<form id ='_ id'methode ='POST'> @ html.antiforgeryToken(); </ form>
ajax調用函數 :
var data={...};
var token=$('#_id').serializeObject();
var dataWithAntiforgeryToken = $.extend(data,token);
$.ajax(
{
....,
data: dataWithAntiforgeryToken;
}
)
我想保護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請求並收到預期的異常。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.