Les scripts de contenu sont exécutés dans un environnement "monde isolé" . Vous devez injecter votre state()
méthode dans la page elle-même.
Lorsque vous souhaitez utiliser l'une des chrome.*
API du script, vous devez implémenter un gestionnaire d'événements spécial, comme décrit dans cette réponse: Extension Chrome - récupérer le message d'origine de Gmail .
Sinon, si vous n'avez pas à utiliser d' chrome.*
API, je vous recommande fortement d'injecter tout votre code JS dans la page via l'ajout d'une <script>
balise:
Table des matières
- Méthode 1: injecter un autre fichier
- Méthode 2: injecter du code incorporé
- Méthode 2b: utilisation d'une fonction
- Méthode 3: utiliser un événement en ligne
- Valeurs dynamiques dans le code injecté
Méthode 1: injecter un autre fichier
C'est la méthode la plus simple / la meilleure lorsque vous avez beaucoup de code. Incluez votre code JS réel dans un fichier au sein de votre extension, par exemple script.js
. Ensuite, laissez votre script de contenu être le suivant (expliqué ici: Javascript personnalisé "Raccourci d'application" Google Chome ):
var s = document.createElement('script');
// TODO: add "script.js" to web_accessible_resources in manifest.json
s.src = chrome.runtime.getURL('script.js');
s.onload = function() {
this.remove();
};
(document.head || document.documentElement).appendChild(s);
Remarque: Si vous utilisez cette méthode, le script.js
fichier injecté doit être ajouté à la "web_accessible_resources"
section ( exemple ). Si vous ne le faites pas, Chrome refusera de charger votre script et affichera l'erreur suivante dans la console:
Refuser la charge de chrome-extension: // [EXTENSIONID] /script.js. Les ressources doivent être répertoriées dans la clé de manifeste web_accessible_resources afin d'être chargées par des pages en dehors de l'extension.
Méthode 2: injecter du code incorporé
Cette méthode est utile lorsque vous souhaitez exécuter rapidement un petit morceau de code. (Voir aussi: Comment désactiver les raccourcis Facebook avec l'extension Chrome? ).
var actualCode = `// Code here.
// If you want to use a variable, use $ and curly braces.
// For example, to use a fixed random number:
var someFixedRandomValue = ${ Math.random() };
// NOTE: Do not insert unsafe variables in this way, see below
// at "Dynamic values in the injected code"
`;
var script = document.createElement('script');
script.textContent = actualCode;
(document.head||document.documentElement).appendChild(script);
script.remove();
Remarque: les littéraux de modèle ne sont pris en charge que dans Chrome 41 et versions ultérieures. Si vous souhaitez que l'extension fonctionne dans Chrome 40-, utilisez:
var actualCode = ['/* Code here. Example: */' + 'alert(0);',
'// Beware! This array have to be joined',
'// using a newline. Otherwise, missing semicolons',
'// or single-line comments (//) will mess up your',
'// code ----->'].join('\n');
Méthode 2b: utilisation d'une fonction
Pour un gros morceau de code, il n'est pas possible de citer la chaîne. Au lieu d'utiliser un tableau, une fonction peut être utilisée et stringifiée:
var actualCode = '(' + function() {
// All code is executed in a local scope.
// For example, the following does NOT overwrite the global `alert` method
var alert = null;
// To overwrite a global variable, prefix `window`:
window.alert = null;
} + ')();';
var script = document.createElement('script');
script.textContent = actualCode;
(document.head||document.documentElement).appendChild(script);
script.remove();
Cette méthode fonctionne, car l' +
opérateur sur les chaînes et une fonction convertit tous les objets en chaîne. Si vous avez l'intention d'utiliser le code plus d'une fois, il est sage de créer une fonction pour éviter la répétition du code. Une implémentation pourrait ressembler à:
function injectScript(func) {
var actualCode = '(' + func + ')();'
...
}
injectScript(function() {
alert("Injected script");
});
Remarque: Étant donné que la fonction est sérialisée, la portée d'origine et toutes les propriétés liées sont perdues!
var scriptToInject = function() {
console.log(typeof scriptToInject);
};
injectScript(scriptToInject);
// Console output: "undefined"
Méthode 3: utiliser un événement en ligne
Parfois, vous voulez exécuter du code immédiatement, par exemple pour exécuter du code avant la création de l' <head>
élément. Cela peut être fait en insérant une <script>
balise avec textContent
(voir méthode 2 / 2b).
Une alternative, mais non recommandée, consiste à utiliser des événements en ligne. Il n'est pas recommandé car si la page définit une stratégie de sécurité du contenu qui interdit les scripts en ligne, les écouteurs d'événements en ligne sont bloqués. Les scripts en ligne injectés par l'extension, en revanche, continuent de s'exécuter. Si vous souhaitez toujours utiliser des événements en ligne, voici comment:
var actualCode = '// Some code example \n' +
'console.log(document.documentElement.outerHTML);';
document.documentElement.setAttribute('onreset', actualCode);
document.documentElement.dispatchEvent(new CustomEvent('reset'));
document.documentElement.removeAttribute('onreset');
Remarque: Cette méthode suppose qu'aucun autre écouteur d'événement global ne gère l' reset
événement. Si tel est le cas, vous pouvez également choisir l'un des autres événements mondiaux. Ouvrez simplement la console JavaScript (F12), saisissez document.documentElement.on
et sélectionnez les événements disponibles.
Valeurs dynamiques dans le code injecté
Parfois, vous devez passer une variable arbitraire à la fonction injectée. Par exemple:
var GREETING = "Hi, I'm ";
var NAME = "Rob";
var scriptToInject = function() {
alert(GREETING + NAME);
};
Pour injecter ce code, vous devez passer les variables comme arguments à la fonction anonyme. Assurez-vous de l'implémenter correctement! Les éléments suivants ne fonctionneront pas :
var scriptToInject = function (GREETING, NAME) { ... };
var actualCode = '(' + scriptToInject + ')(' + GREETING + ',' + NAME + ')';
// The previous will work for numbers and booleans, but not strings.
// To see why, have a look at the resulting string:
var actualCode = "(function(GREETING, NAME) {...})(Hi, I'm ,Rob)";
// ^^^^^^^^ ^^^ No string literals!
La solution est d'utiliser JSON.stringify
avant de passer l'argument. Exemple:
var actualCode = '(' + function(greeting, name) { ...
} + ')(' + JSON.stringify(GREETING) + ',' + JSON.stringify(NAME) + ')';
Si vous avez de nombreuses variables, il vaut la peine de les utiliser JSON.stringify
une fois, pour améliorer la lisibilité, comme suit:
...
} + ')(' + JSON.stringify([arg1, arg2, arg3, arg4]) + ')';
player.addEventListener("onStateChange", state);