L'appel jQuery.ajax échoue dans l'extension Chrome

Je porte une de mes extensions Firefox sur Chrome, et je me heurte à un petit problème avec une requête AJAX. Le code suivant fonctionne bien dans l'extension FF, mais échoue avec un état de "0" dans 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 particulière de l'extension vérifie ce qui se trouve sur le presse-papiers (un autre problème de Chrome que j'ai déjà résolu) et s'il s'agit d'une URL d'image, il envoie une requête HEAD et vérifie l'en-tête de réponse "Content-Type" pour s'assurer que c'est une image . Si c'est le cas, il va revenir vrai, en collant le texte du Presse-papiers dans une balise IMG. Sinon, s'il ressemble à une URL normale qui n'est pas une image, elle l'enveloppe dans une balise A. Si ce n'est pas une URL, il suffit de faire une pâte simple.

Quoi qu'il en soit, l'URL vérifiée est définitivement une image, et fonctionne bien dans FF, mais dans la fonction complète, xhr.status est "0", et l'état est "erreur" lorsque la fonction est terminée. Faire passer le délai d'attente à 10 secondes ne vous aide pas. J'ai vérifié que les images de test devraient revenir en tant que "image / jpeg" lors de l'exécution:

 curl -i -X HEAD <imageURL> 

Je sais aussi que je devrais utiliser les retours de réussite et d'erreur au lieu de compléter, mais ils ne fonctionnent pas non plus. Des idées?

Comme vous avez décrit Chris, dans Content Scripts, vous ne pouvez pas faire de XHRs de domaine croisé. Vous devriez les faire dans une page d'extension telle que Background, Popup ou même Options pour le faire.

Pour plus d'informations sur la limitation du script de contenu, reportez-vous à: http://code.google.com/chrome/extensions/content_scripts.html

Et pour plus d'informations concernant la limitation xhr, reportez-vous à: http://code.google.com/chrome/extensions/xhr.html

J'ai résolu une partie du problème, en fait la plupart. Tout d'abord, comme Brennan et moi-même avons mentionné hier, je devais définir des autorisations dans manifest.json.

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

Ce n'est pas idéal pour donner des autorisations à tous les domaines, mais comme les images peuvent être hébergées dans n'importe quel domaine, il faudra le faire, et je devrai me prémunir contre XSS.

L'autre problème est que Chrome bloque en rien tout dans la section contenu_scripts de faire des appels AJAX, en silence. Cependant, il n'y a pas de restriction sur la page background_page, si vous en avez une. Cette page peut faire appel à n'importe quel AJAX, et Chrome dispose d'une API pour permettre à votre script d'ouvrir un port et de passer des demandes dans 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é. Ça marche!

Mon seul problème est maintenant de déterminer comment faire attendre le script pour que le résultat de l'appel soit défini dans l'événement, au lieu de simplement revenir immédiatement.

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

Si cela vous aide à résoudre votre deuxième problème (ou quelqu'un d'autre): vous pouvez envoyer une demande à votre page de fond comme:

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

La response variable peut être tout ce que vous voulez qu'elle 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 auditeur:

 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 demande AJAX à votre script de contenu et faire ce que vous voulez faire avec elle.

La réponse acceptée est obsolète.

Les scripts de contenu peuvent maintenant créer des requêtes HTMLHttp de cross-site comme des scripts de fond!

Les URL concernées doivent être autorisées dans le manifeste:

 { "name": "My extension", ... "permissions": [ "http://www.google.com/" ], ... } 

Vous pouvez également utiliser des expressions comme:

 "http://*.google.com/" "http://*/" 

Pour obtenir des autorisations plus générales.

Voici le lien vers la documentation.