9

Je suis en train de porter l'une de mes extensions Firefox sur Chrome, et je rencontre un petit problème avec une requête AJAX. Le code suivant fonctionne correctement dans l'extension FF, mais échoue avec un état "0" dans Chrome.L'appel jQuery.ajax échoue dans l'extension 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; 
} 

Cette partie de l'extension vérifie ce qui est le presse-papiers (un autre problème Chrome je l'ai déjà résolu), et si elle est une URL d'image, il envoie une requête HEAD et vérifie la réponse « Content-Type » en-tête pour être sûr que c'est une image. Si c'est le cas, il retournera vrai, en collant le texte du presse-papiers dans un tag IMG. Sinon, si elle ressemble à une URL normale qui n'est pas une image, elle l'enveloppe dans une balise A. Si ce n'est pas une URL, elle fait juste une pâte simple. Quoi qu'il en soit, l'URL vérifiée est définitivement une image, et fonctionne correctement dans FF, mais dans la fonction complète, xhr.status est "0", et l'état est "error" quand la fonction est terminée. Augmenter le délai d'attente à 10 secondes n'aide pas. Je l'ai vérifié les images de test devraient revenir comme « image/jpeg » lors de l'exécution:

curl -i -X HEAD <imageURL> 

Je sais aussi que je devrais utiliser le succès et callbacks d'erreur au lieu de complet, mais ils ne fonctionnent pas non plus. Des idées?

+0

Que ce soit une restriction de sécurité sur toutes les requêtes AJAX de extention? –

+0

ne devrait pas 'return isImage;' faire partie du rappel complet? – pixeline

+0

@pixieline: Ça peut l'être. C'était juste pour avoir un point de retour, mais ça ne va même pas aussi loin, parce que le commutateur (status) est "error", donc cette branche n'est jamais appelée. –

Répondre

11

Comme vous l'avez compris Chris, dans Content Scripts, vous ne pouvez pas faire de XHR inter-domaines. Vous devriez les faire dans une page d'extension comme Background, Popup, ou même Options pour le faire.

Pour plus d'informations concernant la limitation du script de contenu, s'il vous plaît se référer à: http://code.google.com/chrome/extensions/content_scripts.html

Et pour plus d'informations concernant la limitation de XHR, s'il vous plaît se référer à: http://code.google.com/chrome/extensions/xhr.html

+6

Pour tous ceux qui tombent sur cette page, c'est [pas vrai pour Chrome 13+] (http://developer.chrome.com/extensions/whats_new.html#13) – Arithmomaniac

5

Vérifiez votre fichier manifeste. L'extension a-t-elle l'autorisation d'accéder à cette URL?

Si elle aide à votre deuxième problème (ou quelqu'un d'autre): Vous pouvez envoyer une demande à votre page d'arrière-plan comme:

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

Le response variable peut être tout ce que vous voulez qu'il soit. Il peut simplement s'agir d'une chaîne de succès ou de refus. Dépend de vous.

Sur votre page d'arrière-plan vous pouvez ajouter un écouteur:

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. 
}); 

Avec cela, vous pouvez passer la réponse de votre requête AJAX à votre script de contenu et faire ce que vous vouliez faire avec là.

+0

C'était l'un des problèmes. L'autre est que content_scripts ne peut pas envoyer de requêtes AJAX. La page d'arrière-plan peut, cependant, que je vais expliquer dans ma propre réponse. –

5

J'ai résolu une partie du problème, en fait la plupart. Premièrement, comme Brennan et moi l'avons mentionné hier, j'avais besoin de définir des permissions dans manifest.json.

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

Ce n'est pas idéal pour donner des autorisations à tous les domaines, mais étant donné que les images peuvent être hébergées de tout domaine, il faudra le faire, et je vais devoir se prémunir contre XSS.

L'autre problème est que Chrome bloque en effet tout ce qui se trouve dans la section content_scripts lors des appels AJAX, échouant silencieusement. Cependant, il n'y a pas de telle restriction sur la page background_page, si vous en avez une. Cette page peut faire des appels AJAX qu'il veut, et Chrome a une API pour permettre à votre script pour ouvrir un port et passer des demandes à cette page d'arrière-plan. Quelqu'un a écrit un script appelé XHRProxy comme solution de contournement, et je l'ai modifié pour obtenir l'en-tête de réponse appropriée. Ça marche!

Mon seul problème maintenant consiste à déterminer comment faire en sorte que le script attende le résultat de l'appel à définir dans l'événement, au lieu de simplement revenir immédiatement.

+0

Hey, cela ne tient plus, les scripts de contenu peuvent maintenant faire des demandes xml, voir ma réponse. –

Questions connexes