2012-04-16 16 views
5

Tengo un formulario que se envía al servidor a través de jQuery .ajax() POST. Si el formulario pasa la validación en el lado del servidor, el servidor devolverá el resultado en HTML para que el cliente finalice la presentación en consecuencia. Sin embargo, si el formulario no pasa la validación, el servidor devolverá el resultado en JSON, que consiste en los errores de validación.

Ambos tipos de resultado terminarían en el controlador success de .ajax(). Como ambos tipos son posibles, el manejador necesita una forma de determinar si el resultado es HTML o JSON. ¿Cómo puedo hacer eso?

Nota: En la superficie, mi pregunta es similar a this existing SO question pero no son lo mismo. En esa pregunta, solo hay un tipo de datos posible (HTML o JSON), mientras que mi problema es encontrar una forma de tratar con dos posibles tipos de datos (HTML y JSON).

Respuesta

3

Para los datos JSON, typeof(data) serán object. Para los datos html será string.

Al menos con los datos devueltos de las acciones de ASP.NET MVC3, funciona. Supongo que es el tipo de mimo el que decide cómo maneja jquery los datos devueltos.

+0

Ya lo probé con algunas llamadas básicas de Ajax, y parece funcionar bien. Sin embargo, en la respuesta me ganaste por 30 segundos. – adeneo

5

Si deja el parámetro dataType en blanco, jQuery determinará esta basado en el tipo MIME:

dataTypeString

defecto: suposición inteligente (XML, JSON, script o HTML)

El tipo de datos que espera del servidor. Si no se especifica ninguno, jQuery tratará de inferir que en función del tipo MIME de la respuesta

ref: http://api.jquery.com/jQuery.ajax/

+0

Mi problema es que tengo dos bloques de código diferentes para ejecutar, dependiendo del tipo de datos en los que están los datos devueltos. El manejador 'success' tiene una instrucción' if' para averiguar qué bloque de código ejecutar, pero no lo hago Saber qué puede usar la instrucción 'if' para contrastar. – tamakisquare

+1

jQuery ya lo habrá analizado, por lo que será un objeto válido de JavaScript si fue JSON y una cadena si es HTML. – Paystey

+1

@ahmoo: como dice Paystey, puede usar 'typeof (response)' para comprobar si se trata de un 'object' o' string' que se devuelve ... – Ropstah

2

Si no está 100% seguro de que los datos que usted está alimentando a su jQuery está limpio de ataques XSS maliciosos, entonces es posible que pueda usar el método de JavaScript eval() para su ventaja.

Gracias a @SLaks por a suggestion para cambiar esa desagradable eval() que he usado.

Puede utilizar $.parseJSON para convertir una cadena en bruto de texto en un objeto JSON

function ajaxResponse(raw_data){ 
    try{ 
    // eval("var response="+raw_data); // try and avoid this if possible 
    var response = $.parseJSON(raw_data); 
    if (response){ 
     // We have a JSON inside the 'response' variable! 
    } 
    } catch(e){ 
    // We do not have a JSON. 
    // Probably HTML content. 
    // Might be a malformed JSON. 
    } 
} 

como se menciona en el código, ten en cuenta que si se pasa un objeto JSON mal formado entonces su devolución de llamada verá esto como HTML.

Tenga en cuenta que el dataType especificado en su llamada $.ajax() debe ser text para que jQuery no intente analizarlo por usted.


Todos amamos las alternativas que hacen nuestra vida un poco más fácil - aquí hay una para su situación.
¿Por qué no siempre devolver un objeto JSON?Algo como esto quizá:

{"err":"","html":"<div>foobar<\/div>"} 

Y para un error:

{"err":"1","message":"You did not foo all of your bars yet!"} 
+1

No; usa '$ .parseJSON'. – SLaks

+0

@sla - gracias! De hecho, esa es la mejor opción. Editado para reflejar esto. – Lix

2

Use typeof, informará el tipo de datos con los que trata.

FIDDLE

1

Por qué no utilizar JSON para devolver el HTML así?

Lo que suelo hacer es configurar mi objeto JSON devuelto como esto:

{ 
    //s=status, d=data 
    "s":0, //0 means success, other numbers are for different errors 
    "d":{ /* Other JSON object or string here */ } 
} 

Así, en su caso, que haría algo como esto (pseudo):

if (StuffIsValid()) { 
    ResponseWrite('{"s":0,"d":"<html>html code here</html>"}'); 
} else { 
    ResponseWrite('{"s":1,"d":{"errlist":["err1","err2"]}}'); 
} 

Por supuesto , querrá usar la biblioteca JSON incorporada para su lenguaje de elección del lado del servidor en lugar de usar cadenas.

Luego, en su jQuery success devolución de llamada, yo haría un cheque por el valor de s.

$.ajax({ 
    url: 'url', 
    dataType: 'json', 
    success: function(data) { 
     if (data) { 
      //We have a JSON object 
      if (data.s === 0) { 
       //Success! 
       //Do stuff with data.d as a string 
      } else if (data.s === 1) { 
       //Failed validation 
       //Do stuff with data.d as an object 
      } else { 
       //How did this happen? 
      } 
     } else { 
      //Uh oh, no object, user must have been logged out (or something) 
     } 
    }); 

Esto es particularmente útil si el usuario tiene que estar conectado para acceder a la página que está enviando a ya que se puede coger el hecho de que los datos devueltos no era un objeto JSON.

Cuestiones relacionadas