La solicitud de Ajax devuelve 200 OK, pero se desencadena un evento de error en lugar del éxito

805

He implementado una solicitud de Ajax en mi sitio web y estoy llamando al punto final desde una página web. Siempre devuelve 200 OK , pero jQuery ejecuta el evento de error.
Intenté muchas cosas, pero no pude resolver el problema. Estoy agregando mi código a continuación:

Código jQuery

var row = "1";
var json = "{'TwitterId':'" + row + "'}";
$.ajax({
    type: 'POST',
    url: 'Jqueryoperation.aspx?Operation=DeleteRow',
    contentType: 'application/json; charset=utf-8',
    data: json,
    dataType: 'json',
    cache: false,
    success: AjaxSucceeded,
    error: AjaxFailed
});
function AjaxSucceeded(result) {
    alert("hello");
    alert(result.d);
}
function AjaxFailed(result) {
    alert("hello1");
    alert(result.status + ' ' + result.statusText);
}

Código C # para JqueryOpeartion.aspx

protected void Page_Load(object sender, EventArgs e) {
    test();
}
private void test() {
    Response.Write("<script language='javascript'>alert('Record Deleted');</script>");
}

Necesito la ("Record deleted")cadena después de la eliminación exitosa. Puedo eliminar el contenido, pero no recibo este mensaje. ¿Es correcto o estoy haciendo algo mal? ¿Cuál es la forma correcta de resolver este problema?

Pankaj Mishra
fuente
2
¿Se puede ejecutar la salida del JqueryOperation.aspx través de un validador JSON y ver si es válida JSON
parapura rajkumar
1
Como jsonlint.com . También debe verificar los parámetros que envía. Actualmente no ha establecido ningún nombre de parámetro. Si el parámetro es TwitterId, entonces usted tiene que pasar un objeto a data, no es una cadena: data: {TwitterId: row}.
Felix Kling
66
¿La página Jqueryoperation.aspx devuelve JSON (válido)?
Salman A
1
probablemente su código del lado del servidor está lanzando una excepción ... ¿qué está regresando en su bloque catch como respuesta?
Raghav
3
@Raghav, si el servidor arrojó una excepción al procesar la solicitud, entonces el código de retorno HTTP sería 500.
StuperUser

Respuestas:

1118

jQuery.ajaxintenta convertir el cuerpo de respuesta según el dataTypeparámetro especificado o el Content-Typeencabezado enviado por el servidor. Si la conversión falla (por ejemplo, si JSON / XML no es válido), se activa la devolución de llamada de error.


Su código AJAX contiene:

dataType: "json"

En este caso jQuery:

Evalúa la respuesta como JSON y devuelve un objeto JavaScript. [...] Los datos JSON se analizan de manera estricta; cualquier JSON con formato incorrecto se rechaza y se genera un error de análisis. […] También se rechaza una respuesta vacía; el servidor debería devolver una respuesta de nulo o {} en su lugar.

Su código del lado del servidor devuelve un fragmento HTML con 200 OKestado. jQuery esperaba un JSON válido y, por lo tanto, dispara el error de devolución de llamada quejándose parseerror.

La solución es eliminar el dataTypeparámetro de su código jQuery y hacer que el código del lado del servidor regrese:

Content-Type: application/javascript

alert("Record Deleted");

Pero preferiría sugerir devolver una respuesta JSON y mostrar el mensaje dentro de la devolución de llamada exitosa:

Content-Type: application/json

{"message": "Record deleted"}
Salman A
fuente
1
Gracias por su respuesta, ¿puede decirme una cosa? ¿Cómo puedo devolver el valor json del código detrás? Estoy usando Asp.net con C #. Esto resolvió mi problema, pero también puede hacerme saber esto también.
Pankaj Mishra
1
@ Pankaj: es mejor si lo publicas como otra pregunta. Pero una respuesta corta: dos formas de hacer esto (i) en lugar de $.ajaxintentarlo $.getScript. Dentro del script C # del lado del servidor, simplemente ponga alert('Record Deleted');(sin <script>etiqueta) y configure ContentType de su script C # en text/javascript. $.ajaxTambién podría funcionar, pero no puedo recordar cómo, puede ser que solo necesite cambiar dataType: 'script',. Es posible que ya no necesite el controlador de éxito.
Salman A
3
Esta respuesta puede no estar completa. Justo ahora he validado mi JSON en jsonlint.com, dice explícitamente que es un json vaild, pero todavía se activa el evento "error", con xhr.status 200. ¿Qué otras razones pueden existir? - Ramesh Pareek acaba de editar
Ramesh Pareek
2
O simplemente puede eliminar el parámetro "dataType: json"
Piero Alberto
1
Me he encontrado con este mismo problema sin especificar un tipo de datos cuando lo uso $.post. En este caso, jquery adivina un tipo de datos, luego errores cuando no se analiza . Este es un gotcha realmente desagradable y difícil de encontrar. Lo arreglé configurando el tipo de datos en "text".
Mashmagar
31

He tenido buena suerte con el uso de múltiples dataTypes separados por espacios ( jQuery 1.5+ ). Como en:

$.ajax({
    type: 'POST',
    url: 'Jqueryoperation.aspx?Operation=DeleteRow',
    contentType: 'application/json; charset=utf-8',
    data: json,
    dataType: 'text json',
    cache: false,
    success: AjaxSucceeded,
    error: AjaxFailed
});
jaketrent
fuente
1
Según la documentación de JQuery, de manera similar, una cadena abreviada como "jsonp xml" primero intentará convertir de jsonp a xml y, en su defecto, convertirá de jsonp a texto y luego de texto a xml. Por lo tanto, primero intentará convertir el texto a json, y si falla, ¿entonces solo se tratará como texto?
anIBMer
29

Simplemente tiene que eliminar el tipo de datos : "json" en su llamada AJAX

$.ajax({
    type: 'POST',
    url: 'Jqueryoperation.aspx?Operation=DeleteRow',
    contentType: 'application/json; charset=utf-8',
    data: json,
    dataType: 'json', //**** REMOVE THIS LINE ****//
    cache: false,
    success: AjaxSucceeded,
    error: AjaxFailed
});
Philippe Genois
fuente
22

Esto es solo para el registro, ya que me topé con esta publicación cuando buscaba una solución a mi problema que era similar a los OP.

En mi caso, mi solicitud de jQuery Ajax no tuvo éxito debido a la política del mismo origen en Chrome. Todo se resolvió cuando modifiqué mi servidor (Node.js) para hacer:

response.writeHead(200,
          {
            "Content-Type": "application/json",
            "Access-Control-Allow-Origin": "http://localhost:8080"
        });

Literalmente me costó una hora golpear mi cabeza contra la pared. Me siento estúpido ...

Corvin
fuente
1
Gracias Peter, tuve el mismo problema, y ​​el mensaje de advertencia en la consola del navegador está confundido para mí. Por lo que sé, CORS bloquea la solicitud de envío (utilizando la negociación del método de opciones), no tiene sentido ese bloqueo después de que la operación se haya completado. Tal vez es un comportamiento de navegador personalizado ... Lo probé con Firefox. Gracias, su solución resolvió mi problema.
danipenaperez
15

Creo que su página aspx no devuelve un objeto JSON. Su página debería hacer algo como esto (page_load)

var jSon = new JavaScriptSerializer();
var OutPut = jSon.Serialize(<your object>);

Response.Write(OutPut);

Además, intente cambiar su AjaxFailed:

function AjaxFailed (XMLHttpRequest, textStatus) {

}

textStatus debería darte el tipo de error que estás recibiendo.

LeftyX
fuente
12

Me he enfrentado a este problema con una biblioteca jQuery actualizada. Si el método de servicio no devuelve nada, significa que el tipo de devolución sí lo es void.

Luego, en su llamada Ajax por favor mencione dataType='text'.

Resolverá el problema.

Suresh Vadlakonda
fuente
8

Solo tiene que eliminar dataType: 'json'de su encabezado si su método de servicio web implementado es nulo.

En este caso, la llamada Ajax no espera tener un tipo de datos de retorno JSON.

Bilel omrani
fuente
4

Use el siguiente código para asegurarse de que la respuesta esté en formato JSON (versión PHP) ...

header('Content-Type: application/json');
echo json_encode($return_vars);
exit;
Terry Lin
fuente
4

Tuve el mismo problema. Mi problema era que mi controlador estaba devolviendo un código de estado en lugar de JSON. Asegúrese de que su controlador devuelva algo como:

public JsonResult ActionName(){
   // Your code
   return Json(new { });
}
Alexander Suleymanov
fuente
3

Tengo el problema similar pero cuando intenté eliminar el tipo de datos: 'json' todavía tengo el problema. Mi error se está ejecutando en lugar del éxito

function cmd(){
    var data = JSON.stringify(display1());
    $.ajax({
        type: 'POST',
        url: '/cmd',
        contentType:'application/json; charset=utf-8',
        //dataType:"json",
        data: data,
        success: function(res){
                  console.log('Success in running run_id ajax')
                  //$.ajax({
                   //   type: "GET",
                   //   url: "/runid",
                   //   contentType:"application/json; charset=utf-8",
                   //   dataType:"json",
                   //   data: data,
                   //  success:function display_runid(){}
                  // });
        },
        error: function(req, err){ console.log('my message: ' + err); }
    });
}
Rakesh Kumar
fuente
Estoy viendo lo mismo. La respuesta vacía con un código 200 sigue activando el controlador de errores.
doublejosh
2

Otra cosa que me arruinó las cosas fue usar en localhostlugar de 127.0.0.1 o viceversa. Aparentemente, JavaScript no puede manejar solicitudes de uno a otro.

Pablo
fuente
2

Mira esto . También es un problema similar. Trabajando lo intenté.

No quitar dataType: 'JSON',

Nota: echo solo formato JSON en el archivo PHP si usa solo php echo su código ajax devuelve 200

Inderjeet
fuente
1

Yo tuve el mismo problema. Fue porque mi respuesta JSON contiene algunos caracteres especiales y el archivo del servidor no estaba codificado con UTF-8, por lo que la llamada Ajax consideró que esta no era una respuesta JSON válida.

Mehdi Izcool
fuente
1

Si siempre devuelve JSON desde el servidor (sin respuestas vacías), dataType: 'json'debería funcionar y contentTypeno es necesario. Sin embargo, asegúrese de que la salida JSON ...

¡jQuery AJAX lanzará un 'parseerror' en JSON válido pero no serializado!

Fabian von Ellerts
fuente
-1

Su secuencia de comandos exige un retorno en el tipo de datos JSON.

Prueba esto:

private string test() {
  JavaScriptSerializer js = new JavaScriptSerializer();
 return js.Serialize("hello world");
}
Kashif Faraz
fuente
-9

Intenta seguir

$.ajax({
    type: 'POST',
    url: 'Jqueryoperation.aspx?Operation=DeleteRow',
    contentType: 'application/json; charset=utf-8',
    data: { "Operation" : "DeleteRow", 
            "TwitterId" : 1 },
    dataType: 'json',
    cache: false,
    success: AjaxSucceeded,
    error: AjaxFailed
});

O

$.ajax({
    type: 'POST',
    url: 'Jqueryoperation.aspx?Operation=DeleteRow&TwitterId=1',
    contentType: 'application/json; charset=utf-8',
    dataType: 'json',
    cache: false,
    success: AjaxSucceeded,
    error: AjaxFailed
});

Use comillas dobles en lugar de comillas simples en el objeto JSON. Creo que esto resolverá el problema.

Salman Riaz
fuente