9

Estoy trasladando una de mis extensiones de Firefox a Chrome, y estoy teniendo un pequeño problema con una consulta de AJAX. El siguiente código funciona bien en la extensión FF, pero falla con un estado de "0" en Chrome.La llamada a jQuery.ajax falla dentro de la extensión de Chrome

function IsImage(url) { 
    var isImage = false; 
    var reImageContentType = /image\/(jpeg|pjpeg|gif|png|bmp)/i; 
    var reLooksLikeImage = /\.(jpg|jpeg|gif|png|bmp)/i; 

    if(!reLooksLikeImage.test(url)) 
    { 
     return false; 
    } 

    var xhr = $.ajax({ 
     async: false, 
     type: "HEAD", 
     url: url, 
     timeout: 1000, 
     complete : function(xhr, status) { 
      switch(status) 
      { 
       case "success": 
        isImage = reImageContentType.test(xhr.getResponseHeader("Content-Type")); 
        break; 
      } 
     }, 
    }); 

    return isImage; 
} 

Esta parte de la extensión comprueba lo que hay en el portapapeles (otro tema Chrome ya he resuelto), y si es una URL de la imagen, envía una petición HEAD y comprueba la respuesta "Content-Type" encabezado para asegurarse de que sea una imagen. De ser así, devolverá verdadero, pegando el texto del portapapeles en una etiqueta IMG. De lo contrario, si se ve como una URL normal que no es una imagen, la envuelve en una etiqueta A. Si no es una URL, solo hace un simple pegado.

De todos modos, la url que se comprueba es definitivamente una imagen, y funciona bien en FF, pero en la función completa, xhr.status es "0" y el estado es "error" cuando la función finaliza. Aumentar el tiempo de espera a 10 segundos no ayuda. He verificado las imágenes de prueba deben volver como "image/jpeg" cuando se ejecuta:

curl -i -X HEAD <imageURL> 

también sé que debería usar el éxito y devoluciones de llamada de error en lugar de completo, pero que no funcionan bien. ¿Algunas ideas?

+0

Que sea una restricción de seguridad en todas las peticiones AJAX de extensión? –

+0

no debe 'devolver isImage;' ser parte de la devolución de llamada completa? – pixeline

+0

@pixieline: puede ser. Eso era solo para tener un punto de retorno, pero ni siquiera llega tan lejos, porque el cambio (estado) es "error", por lo que nunca se llama a esa rama. –

Respuesta

11

Como descubriste Chris, en las secuencias de comandos de contenido, no puedes hacer ningún XHR de dominio cruzado. Tendría que hacerlas en una página de extensión como Fondo, Emergente o incluso Opciones para hacerlo.

Para obtener más información sobre la limitación de la escritura de contenido, por favor referirse a: http://code.google.com/chrome/extensions/content_scripts.html

Y para más información sobre la limitación xhr, consulte: http://code.google.com/chrome/extensions/xhr.html

+6

Para cualquier persona que tropiece en esta página, esto es [no es cierto para Chrome 13+] (http://developer.chrome.com/extensions/whats_new.html#13) – Arithmomaniac

5

Verifique su archivo de manifiesto. ¿La extensión tiene permiso para acceder a esa url?

Si ayuda a su segundo problema (o cualquier otro): puede enviar una solicitud a su página de fondo como:

chrome.extension.sendRequest({var1: "var1value", var2: "value", etc}, 
function(response) { 
    //Do something once the request is done. 
}); 

La variable response puede ser lo que quiera que sea. Simplemente puede ser un éxito o una cadena denegada. Depende de usted.

En su página de fondo se puede añadir un detector:

chrome.extension.onRequest.addListener(
function(request, sender, sendResponse) { 
     // Do something here 
     // Once done you can send back all the info via: 
     sendResponse(anything you want here); 

     // and it'll be passed back to your content script. 
}); 

Con esto se puede pasar a la respuesta de su petición AJAX volver a su script contenido y hacer lo que quería hacer con ella allí.

+0

Ese fue uno de los problemas. El otro es que content_scripts no puede enviar solicitudes AJAX. La página de fondo puede, sin embargo, que explicaré en mi propia respuesta. –

5

He resuelto parte del problema, en realidad la mayor parte. Primero, como Brennan y yo mencionamos ayer, necesitaba establecer permisos en manifest.json.

"permissions": [ 
    "http://*/*", 
    "https://*/*" 
], 

no es ideal para dar permisos a cada dominio, pero ya que las imágenes se pueden alojar de cualquier dominio, se tendrá que hacer, y voy a tener que protegerse contra XSS.

El otro problema es que Chrome efectivamente bloquea cualquier cosa en la sección content_scripts de hacer llamadas AJAX, fallando silenciosamente. Sin embargo, no existe tal restricción en background_page, si tiene una. Esa página puede realizar cualquier llamada AJAX que desee, y Chrome tiene una API para permitir que su secuencia de comandos abra un puerto y pase solicitudes a esa página de fondo. Alguien escribió un script llamado XHRProxy como una solución, y lo modifiqué para obtener el encabezado de respuesta apropiado. ¡Funciona!

Mi único problema ahora es averiguar cómo hacer que el script espere a que se establezca el resultado de la llamada en el evento, en lugar de simplemente regresar de inmediato.

+0

Oye, esto ya no es válido, las secuencias de comandos de contenido ahora pueden realizar solicitudes XML, ver mi respuesta. –

Cuestiones relacionadas