Estoy intentando escribir un script de usuario que realiza una solicitud AJAX de dominio cruzado.

He incluido jQuery dentro de mi script usando @require y todo parece estar funcionando bien hasta el punto en que trato de ejecutar jQuery.getJSON.

La API a la que estoy accediendo admite jsonp, sin embargo, sigo recibiendo un error que indica que jsonp123456789 no está definido.

Por lo que he podido recopilar, esto se debe a que jQuery escribe la respuesta jsonp directamente en el encabezado de la página, que luego se convierte en sandbox. Una vez que eso ha ocurrido, jQuery ya no puede acceder a la devolución de llamada, lo que hace que no esté definida. (No estoy al 100% en este caso, pero me parece probable).

¿Hay alguna forma de evitar esto? Se ha sugerido que declare la función de devolución de llamada dentro de unsafeWindow, pero no estoy seguro de cómo hacerlo y no he logrado que funcione.

11
user199348 30 oct. 2009 a las 04:11

3 respuestas

La mejor respuesta

¿No sería bueno que jQuery usara GM_xmlhttpRequest internamente para que pudieras tener toda la conveniencia de los métodos jQuery y la funcionalidad entre sitios de Greasemonkey? Como señala mahemoff, Greasemonkey podría permitirle hacer la solicitud sin depender de JSONP y encontrarse con el problema de devolución de llamada que enfrenta, pero tendrá que lidiar con el contenido de JSON usted mismo.

Hemos escrito una biblioteca que hará exactamente eso: el Greasemonkey / Puente jQuery XHR. Si @require ese script en su script de usuario, entonces todas $.get y $.getJSON y $.post, etc. las llamadas jQuery funcionarán en todos los sitios sin depender de técnicas como JSONP.

Entonces, si usa este puente y simplemente elimina el ?callback=? de su URL, su código jQuery debería funcionar sin modificaciones. Esta publicación de blog proporciona un tutorial paso a paso. Si alguien tiene alguna pregunta, comentario, informe de error o sugerencia sobre el complemento del puente, hágamelo saber.

16
npdoty 1 nov. 2009 a las 21:03

Como muchos sabrán, Google Chrome no admite ninguna de las prácticas funciones de GM_ en este momento.

Como tal, es imposible realizar solicitudes AJAX entre sitios debido a varias restricciones de sandbox (incluso utilizando excelentes herramientas como Script de solicitud de dominio cruzado de James Padolsey)

Necesitaba una manera para que los usuarios supieran cuándo mi script Greasemonkey se había actualizado en Chrome (ya que Chrome tampoco hace eso ...). Se me ocurrió una solución que está documentada aquí (y en uso en mi Lighthouse ++ script) y Vale la pena leerlo para aquellos de ustedes que quieran verificar la versión de sus scripts:

http://blog.bandit.co.nz/post/1048347342/version-check-chrome-greasemonkey-script

1
James Nisbet 1 sep. 2010 a las 16:21

La solución es usar GM_HttpRequest. Puede salirse con la suya, en lugar de JSONP para solicitudes de dominio cruzado, porque a diferencia del XHR habitual, GM_HttpRequest permite llamadas de dominio cruzado. Quieres algo como:

  GM_xmlhttpRequest({
     method: "GET",
     url: "http://example.com/path/to/json",
     onload: function(xhr) {
      var data = eval("(" + xhr.responseText + ")");
      // use data ...
    }
  });

Tenga en cuenta que esta evaluación es JSON de la manera más simple. Si desea una solución más segura para JSON no confiable, deberá incluir una pequeña biblioteca de análisis JSON.

Desafortunadamente, también tiene que envolver un setTimeout de duración cero aparentemente inútil alrededor de todo el asunto. Me resulta más fácil pegar el GM_xmlhttpRequest en su propio método, luego ejecutar setTimeout (makeCall, 0) ;.

Puede ver un ejemplo real aquí.

8
brasofilo 11 sep. 2014 a las 14:56