Cause sous-jacente :
Les scripts de contenu sont exécutés dans une "monde isolé" l'environnement.
Solution :
Injectez le code dans la page en utilisant le DOM - ce code sera capable de accès fonctions/variables du contexte de la page ("monde principal") ou exposer aux fonctions/variables du contexte de la page (dans votre cas, il s'agit de la fonction state()
méthode).
-
A noter au cas où la communication avec la page script est nécessaire :
Utiliser DOM CustomEvent
manipulateur. Exemples : un , deux y trois .
-
Note en cas chrome
API est nécessaire dans la page script :
Desde chrome.*
Les API ne peuvent pas être utilisées dans la page script, vous devez les utiliser dans le contenu script et envoyer les résultats à la page script via la messagerie DOM (voir la note ci-dessus).
Avertissement de sécurité :
Une page peut redéfinir ou augmenter un prototype intégré, de sorte que votre code exposé peut échouer si la page le fait d'une manière incompatible. Si vous voulez vous assurer que votre code exposé s'exécute dans un environnement sûr, vous devez soit a) déclarer votre contenu script avec "run_at" : "document_start" et utiliser les méthodes 2-3 et non 1, ou b) extraire les modules d'origine via une iframe vide, exemple . Notez qu'avec document_start
vous devrez peut-être utiliser DOMContentLoaded
dans le code exposé pour attendre le DOM.
Table des matières
- Méthode 1 : Injecter un autre fichier - compatible avec ManifestV3
- Méthode 2 : Injection de code embarqué
- Méthode 2b : Utilisation d'une fonction
- Méthode 3 : Utilisation d'un événement en ligne - compatible avec ManifestV3
- Méthode 4 : Utilisation du monde d'executeScript - ManifestV3 seulement
- Valeurs dynamiques dans le code injecté
Méthode 1 : Injecter un autre fichier - compatible avec ManifestV3
Particulièrement utile lorsque vous avez beaucoup de code. Mettez le code dans un fichier dans votre extension, par exemple script.js
. Puis le charger dans votre contenu script comme ça :
var s = document.createElement('script');
s.src = chrome.runtime.getURL('script.js');
s.onload = function() {
this.remove();
};
(document.head || document.documentElement).appendChild(s);
Le fichier js doit être exposé dans web_accessible_resources
:
-
Exemple de manifest.json pour ManifestV2
"web_accessible_resources": ["script.js"],
-
Exemple de manifest.json pour ManifestV3
"web_accessible_resources": [{
"resources": ["script.js"],
"matches": ["<all_urls>"]
}]
Sinon, l'erreur suivante apparaîtra dans la console :
Refus de chargement de chrome-extension://[EXTENSIONID]/script.js. Les ressources doivent être répertoriées dans la clé manifeste web_accessible_resources pour pouvoir être chargées par des pages extérieures à l'extension.
Méthode 2 : Injection d'un code embarqué
Cette méthode est utile lorsque vous souhaitez exécuter rapidement un petit morceau de code. (Voir aussi : Comment désactiver les touches de raccourci de 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();
Note : littéraux de modèle ne sont prises en charge qu'à partir de la version 41 de Chrome. 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 de caractères. Au lieu d'utiliser un tableau, on peut utiliser une fonction et la transformer en chaîne :
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 le +
sur les chaînes de caractères et une fonction convertit tous les objets en chaîne de caractères. 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 à ceci :
function injectScript(func) {
var actualCode = '(' + func + ')();'
...
}
injectScript(function() {
alert("Injected script");
});
Remarque : Comme la fonction est sérialisée, la portée originale 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 : Utilisation d'un événement en ligne - compatible avec ManifestV3
Parfois, vous voulez exécuter un certain code immédiatement, par exemple avant que la fonction <head>
est créé. Cela peut être fait en insérant un <script>
tag avec textContent
(voir méthode 2/2b).
Une alternative, mais non recommandé est d'utiliser des événements en ligne. Ce n'est pas recommandé car si la page définit une politique de sécurité du contenu qui interdit les scripts en ligne, alors les écouteurs d'événements en ligne sont bloqués. Les scripts en ligne injectés par l'extension, par contre, s'exécutent quand même. Si vous voulez toujours utiliser les é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'il n'y a pas d'autres écouteurs d'événements globaux qui gèrent l'événement reset
événement. Si c'est le cas, vous pouvez également choisir l'un des autres événements globaux. Il suffit d'ouvrir la console JavaScript (F12), de taper document.documentElement.on
et choisissez l'un des événements disponibles.
Méthode 4 : Utilisation du monde d'executeScript - ManifestV3 seulement
Dans Chrome 95 ou plus récent, utilisez chrome.scripting.executeScript
con world: 'MAIN'
dans votre extension script comme le fond script ou la popup script, mais pas dans le contenu script.
Voir le documentation y exemples .
Valeurs dynamiques dans le code injecté
Occasionnellement, 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. Veillez à l'implémenter correctement ! Ce qui suit no travail :
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 consiste à utiliser JSON.stringify
avant de passer l'argument. Exemple :
var actualCode = '(' + function(greeting, name) { ...
} + ')(' + JSON.stringify(GREETING) + ',' + JSON.stringify(NAME) + ')';
Si vous avez beaucoup de variables, il vaut la peine d'utiliser la fonction JSON.stringify
une fois, pour améliorer la lisibilité, comme suit :
...
} + ')(' + JSON.stringify([arg1, arg2, arg3, arg4]) + ')';
19 votes
Essayez d'enlever les guillemets autour du nom de votre fonction :
player.addEventListener("onStateChange", state);
4 votes
Il est également à noter que lors de la rédaction des correspondances, n'oubliez pas d'inclure
https://
ohttp://
cewww.youtube.com/*
ne vous laisserait pas emballer l'extension et jetterait Erreur de séparateur de schéma manquant1 votes
Voir aussi bugs.chromium.org/p/chromium/issues/detail?id=478183