2011-05-18 981 views
25

Así que estoy tratando de hacer una solicitud al API Stack Exchange con el siguiente código de jQuery:solicitud JSONP error de regresar: "SyntaxError no detectada: símbolo inesperado:"

$.ajax({                                                   
    type: 'POST',                                                 
    url: 'http://api.stackoverflow.com/1.1/stats',                                    
    dataType: 'jsonp',                                                 
    success: function() { console.log('Success!'); },                                              
    error: function() { console.log('Uh Oh!'); }                                        
}); 

Pero cuando abro el archivo en mi máquina, ya sea Firefox o Chrome, y hacer el pedido, me sale este error:

Resource interpreted as Script but transferred with MIME type application/json. 
Uncaught SyntaxError: Unexpected token : 
Uh Oh! 

que no tienen ni idea de lo que está pasando. Sé que Stack Exchange API Gzips sus respuestas, ¿esto causaría algún problema?

+0

¿Qué se obtiene desde el servidor? Obtengo JSON, y JSON no es JSON-P, que encapsula los datos en una función de devolución de llamada, que debe estar en su espacio de nombres global, y que le comunicó al servidor en su solicitud (algo que no veo en su código)) El punto es que simplemente no le digas a tu jQuery que el resultado es JSONP si realmente es JSON. –

+3

Utilicé JSONP porque se sugirió en otro lugar en StackOverflow. Cuando uso JSON obtengo este error: 'XMLHttpRequest no puede cargar http://api.stackoverflow.com/1.1/stats. El nulo de origen no está permitido por Access-Control-Allow-Origin. – theabraham

+0

No se conoce su API, pero lo que se devuelve de esa URL es claramente JSON, como ya he dicho. Con "dataType" solo le dices * a tu jQuery * cómo interpretar el resultado, no le dices al * servidor * que quieres JSONP. –

Respuesta

20

Tiene que establecer un parámetro no convencional para que la SO API funcione. En lugar del callback convencional, debe pasar un parámetro jsonp.

Además, no puede hacer POST con JSONP.

$.ajax({                                                   
    type: 'GET',                                                 
    url: 'http://api.stackoverflow.com/1.1/stats',                                    
    dataType: 'jsonp',                                                 
    success: function() { console.log('Success!'); },                                              
    error: function() { console.log('Uh Oh!'); }, 
    jsonp: 'jsonp'                                     
}); 

No es posible hacer AJAX entre dominios usando el XMLHTTPRequest convencional. Esto es por razones de seguridad (se llama la misma política de origen).

Hay una solución. Las etiquetas script no están sujetas a esta restricción. Esto significa que puede insertar una etiqueta script en el documento que llama a una URL. Si define una función de acceso global en su secuencia de comandos y le dice al servidor remoto cómo se llama esa función, el servidor puede pasar el código que envuelve los datos que se enviarán en una llamada a esa función.

La dificultad que tienes aquí es con la API de StackOverflow. Convencionalmente, usaría el argumento callback en su solicitud, para decirle al servidor a qué se llama su función. Sin embargo, la API de StackOverflow le pide que use el parámetro jsonp en su lugar.

+1

"jsonp" es el parámetro, pero su valor es el nombre de una función en el espacio de nombres global, que se llama cuando se encuentran los resultados. –

+0

Esto funciona, pero ¿podría explicar brevemente por qué? – theabraham

+0

Como ya he dicho, vea los comentarios a su Q, tiene que decirle a EL SERVIDOR que quiere JSONP, ¡o le envía JSON!cómo depende del servidor, este quiere un parámetro "jsonp" con el nombre de la función de devolución de llamada. –

4

probar este URL: http://api.stackoverflow.com/1.1/stats?jsonp=callme

"callme" es el nombre de la función de devolución de llamada - en su espacio de nombres global (objeto de la ventana).

Por cierto, si está ejecutando Firefox y tiene instalado el complemento JSONView, puede probar la URL anterior (y la suya para compararla) directamente.

resultado de llamar a la URL:

callme({ 
    "statistics": [ 
... 
    ] 
}) 
Cuestiones relacionadas