web-dev-qa-db-fra.com

Chargement de javascript externe dans google chrome

J'écris une Google Chrome qui manipule la page actuelle (ajoute essentiellement un bouton).

Dans mon script de contenu, je veux charger l'API Facebook Graph:

$fbDiv = $(document.createElement('div')).attr('id', 'fb-root');
$fbScript = $(document.createElement('script')).attr('src', 'https://connect.facebook.net/en_US/all.js');
$(body).append($fbDiv);
$(body).append($fbScript);

console.log("fbScript: " + typeof $fbScript.get(0));
console.log("fbScript parent: " + typeof $fbScript.parent().get(0));
console.log("find through body: " + typeof $(body).find($fbScript.get(0)).get(0));

Cependant, le script ne semble pas ajouté à body. Voici le journal de la console:

fbScript: object
fbScript parent: undefined
find through body: undefined

Des idées sur ce que je fais mal?

26
Gezim

Le problème est que le JavaScript à l'intérieur des scripts de contenu s'exécute dans son propre environnement en bac à sable et n'a accès qu'à d'autres JavaScript qui ont été chargés de l'une des deux manières suivantes:

Via le manifeste :

{
  "name": "My extension",
  ...
  "content_scripts": [
    {
      "js": ["https://connect.facebook.net/en_US/all.js"]
    }
  ],
  ...
}

Ou en utilisant injection programmatique :

/* in background.html */
chrome.browserAction.onClicked.addListener(function(tab) {
    chrome.tabs.executeScript(null,
                       {file:"https://connect.facebook.net/en_US/all.js"});
});

Assurez-vous de mettre à jour vos autorisations de manifeste:

/* in manifest.json */
"permissions": [
    "tabs", "https://connect.facebook.net"
 ], 

L'ajout d'une balise de script évaluera en effet le JavaScript dans le contexte de la page contenant, en dehors du sandbox JavaScript auquel votre JavaScript a accès.

De plus, comme le script FB requiert que le "fb-root" soit dans le DOM, vous devrez probablement utiliser l'approche programmatique pour pouvoir d'abord mettre à jour le DOM avec l'élément, puis passer un message = retour à la page d'arrière-plan pour charger le script Facebook afin qu'il soit accessible au JavaScript qui est chargé dans les scripts de contenu.

42
Adam Ayres

Google Chrome ne permettent plus d'injecter directement du code externe, mais vous pouvez toujours télécharger le code avec un appel Ajax et le nourrir à l'injecteur comme s'il s'agissait d'un bloc de code.

chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
    $.get("http://127.0.0.1:8000/static/plugin/somesite.js", function(result) {
        chrome.tabs.executeScript(tabs[0].id, {code: result});
    }, "text");
});

source: https://stackoverflow.com/a/36645710/720665

6
David Salamon