jquery - section - razor javascript
Cómo hacer una solicitud de ajax con token anti falsificación en mvc (5)
Tengo un problema con los detalles a continuación del proyecto MVC.
Cuando trato de usar la solicitud jquery ajax con un panel de carga como spinning gif (o incluso texto), recibo un error, observado por el violinista que
El campo de formulario antifalsificación requerido "__RequestVerificationToken" no está presente.
Si comento el [ValidateAntiForgeryToken] attribute
en el método de acción POST y uso el panel de carga, está funcionando bien. Deseo saber por qué recibo este error.
Incluso he usado la cadena de consulta serializada con
__RequestVerificationToken= $(''input[name="__RequestVerificationToken"'').val()
Todavía estoy recibiendo un error
El token anti falsificación no se pudo descifrar. Si esta aplicación está alojada en una Web Farm o clúster, asegúrese de que todas las máquinas ejecuten la misma versión de páginas web ASP.NET y de que la configuración
<machineKey>
especifique claves de cifrado y validación explícitas.
AutoGenerate no se puede usar en un clúster
¿Qué debería usar?
Aquí se actualizó el código de pregunta
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;
}
});
}
});
etiquetas de formulario
<form action="/TransportJob/Create" method="post"><input name="__RequestVerificationToken" type="hidden" value="ydYSei0_RfyBf619dQrhDwwoCM7OwWkJQQEMNvNdAkefiFfYvRQ0MJYYu0zkktNxlJk_y1ZJO9-yb- COap8mqd0cvh8cDYYik4HJ0pZXTgE1" />
Etiqueta de formulario TransportJob 2 en la misma página
<form action="/TransportJobAddress/Create" method="post" novalidate="novalidate"><input name="__RequestVerificationToken" type="hidden" value="Np2vUZJPk1TJlv846oPSU6hg4SjMHRcCk1CacaqZbpHOg8WbV4GZv06noRDl7F_iT9qQf3BIXo3n9wGW68sU mki7g3-ku_BSHBDN-g2aaKc1">
¿Ha agregado su token al encabezado de la llamada ajax?
Debe agregar AntiForgeryToken en el encabezado de su mensaje en la llamada ajax:
var token = $(''input[name="__RequestVerificationToken"]'').val();
var headers = {};
headers[''__RequestVerificationToken''] = token;
$.ajax({
url: ... some url,
headers: headers,
....
});
Prueba esto en tu código:
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;
}
});
}
});
Se agregó línea de encabezados en tu llamada ajax.
¿Has agregado el token a tu Vista? Me gusta esto:
<form method="post" action="/my-controller/my-action">
@Html.AntiForgeryToken()
</form>
Como el controlador que recibe la publicación está buscando el token anti falsificación, debe asegurarse de agregarlo a su formulario en la vista.
EDITAR:
Intente construir sus datos en json primero:
var formData = $(''form[action="/TransportJobAddress/Create"]'').serialize();
$.extend(formData, {''__RequestVerificationToken'': token });
//and then in your ajax call:
$.ajax({
//...
data:formData
//...
});
En lugar de agregarlo manualmente a cada solicitud, generalmente hago algo como esto:
var token = $(''input[name="__RequestVerificationToken"]'').val();
$.ajaxPrefilter(function (options, originalOptions) {
if (options.type.toUpperCase() == "POST") {
options.data = $.param($.extend(originalOptions.data, { __RequestVerificationToken: token }));
}
});
Esto agregará automáticamente tu token a cualquier POST ajax que hagas.
Quería asegurar tanto Ajax como la solicitud normal, así que esto es lo que surgió:
Primero usando el excelente blog de haacked.com Creé el ConditionalFilterProvider como se describe.
Luego creé todas las clases como se describe en el blog de codethinked .
En mi página de distribución agregué la pieza con $ .ajaxPrefilter como se describe en el blog ... Esto asegura que toda mi devolución de llamada Ajax ahora envía el token Antiforgery a través del encabezado.
Para unir todos agregué este fragmento de código en mi 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
Básicamente ... inyecte el atributo a todos mis Controladores que no son GET.
Después de eso tuve que ir a todos mis (Muy pocos) formularios y agregar el @ Html.AntiForgeryToken ().
Para probar que todo funcionó, intenté ocultar cosas con un formulario sin AntiForgeryToken y obtuve la excepción esperada. Y elimine $ .ajaxPrefilter y cree solicitudes Ajax y se reciba la excepción esperada.
Ver o diseño:
<form id = ''_ id'' method = ''POST''> @ html.antiforgeryToken (); </ form>
La función de llamada ajax :
var data={...};
var token=$(''#_id'').serializeObject();
var dataWithAntiforgeryToken = $.extend(data,token);
$.ajax(
{
....,
data: dataWithAntiforgeryToken;
}
)