J'ai un problème avec les détails ci-dessous du projet MVC.
Lorsque j'essaie d'utiliser la demande jquery ajax avec le panneau de chargement comme le spin gif (ou même du texte), je reçois une erreur, observée par le violoniste qui
Le champ de formulaire anti-contrefaçon obligatoire "__RequestVerificationToken" n'est pas présent.
Si je commente [ValidateAntiForgeryToken] attribute
at POST et utilisation du panneau de chargement, cela fonctionne bien. Je veux savoir pourquoi j'obtiens cette erreur.
J'ai même utilisé la chaîne de requête sérialisée avec
__RequestVerificationToken= $('input[name="__RequestVerificationToken"').val()
je reçois toujours une erreur
Le jeton anti-contrefaçon n'a pas pu être déchiffré. Si cette application est hébergée par une batterie de serveurs ou un cluster Web, assurez-vous que toutes les machines exécutent la même version des pages Web ASP.NET et que le
<machineKey>
la configuration spécifie des clés de chiffrement et de validation explicites.
AutoGenerate ne peut pas être utilisé dans un cluster
Que dois-je utiliser?
Ici, il a mis à jour le code de question
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;
}
});
}
});
balises de formulaire
<form action="/TransportJob/Create" method="post"><input name="__RequestVerificationToken" type="hidden" value="ydYSei0_RfyBf619dQrhDwwoCM7OwWkJQQEMNvNdAkefiFfYvRQ0MJYYu0zkktNxlJk_y1ZJO9-yb- COap8mqd0cvh8cDYYik4HJ0pZXTgE1" />
Balise de formulaire TransportJob 2 sur la même page
<form action="/TransportJobAddress/Create" method="post" novalidate="novalidate"><input name="__RequestVerificationToken" type="hidden" value="Np2vUZJPk1TJlv846oPSU6hg4SjMHRcCk1CacaqZbpHOg8WbV4GZv06noRDl7F_iT9qQf3BIXo3n9wGW68sU mki7g3-ku_BSHBDN-g2aaKc1">
Avez-vous ajouté votre jeton à l'en-tête de l'appel ajax?
Vous devez ajouter AntiForgeryToken dans votre en-tête de message lors de l'appel ajax:
var token = $('input[name="__RequestVerificationToken"]').val();
var headers = {};
headers['__RequestVerificationToken'] = token;
$.ajax({
url: ... some url,
headers: headers,
....
});
Essayez ceci dans votre 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;
}
});
}
});
Ligne d'en-têtes ajoutée dans votre appel ajax.
Plutôt que de l'ajouter manuellement à chaque demande, je fais généralement quelque chose comme ceci:
var token = $('input[name="__RequestVerificationToken"]').val();
$.ajaxPrefilter(function (options, originalOptions) {
if (options.type.toUpperCase() == "POST") {
options.data = $.param($.extend(originalOptions.data, { __RequestVerificationToken: token }));
}
});
Cela ajoutera automatiquement votre jeton à n'importe lequel ajax POST vous le faites.
Avez-vous ajouté le jeton à votre vue? Comme ça:
<form method="post" action="/my-controller/my-action">
@Html.AntiForgeryToken()
</form>
Étant donné que votre contrôleur recevant le message recherche le jeton anti contrefaçon, vous devez vous assurer de l'ajouter à votre formulaire dans la vue.
MODIFIER:
Essayez d'abord de créer vos données dans json:
var formData = $('form[action="/TransportJobAddress/Create"]').serialize();
$.extend(formData, {'__RequestVerificationToken': token });
//and then in your ajax call:
$.ajax({
//...
data:formData
//...
});
Affichage ou mise en page:
<form id = '_ id' method = 'POST'> @ html.antiforgeryToken (); </ formulaire>
La fonction d'appel ajax:
var data={...};
var token=$('#_id').serializeObject();
var dataWithAntiforgeryToken = $.extend(data,token);
$.ajax(
{
....,
data: dataWithAntiforgeryToken;
}
)
Je voulais sécuriser à la fois Ajax et la demande normale, alors voici ce que j'ai sorti:
En utilisant d'abord l'excellent blog de haacked.com J'ai créé le ConditionalFilterProvider comme décrit.
Ensuite, j'ai créé toutes les classes comme décrit sur le blog de codethinked .
Sur ma page _layout, j'ai ajouté le morceau avec le $ .ajaxPrefilter comme décrit dans le blog ... Cela garantit que tous mes rappels Ajax envoient maintenant le jeton Antiforgery via l'en-tête.
Pour coller tous ensemble, j'ai ajouté ce morceau de code sur mon 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
Fondamentalement ... injectez l'attribut à tous mes contrôleurs qui ne sont pas GET.
Après cela, je devais simplement aller à tous mes (très peu) formulaires et ajouter le @ Html.AntiForgeryToken ().
Pour prouver que tout a fonctionné, j'essaie simplement de densifier les choses avec un formulaire sans AntiForgeryToken et d'obtenir l'exception attendue. Et supprimez le $ .ajaxPrefilter et créez des demandes Ajax et l'exception attendue a été reçue.