Passer un paramètre à un script contenu injectée à l'aide de chrome.onglets.executeScript()
Comment puis-je passer un paramètre pour le JavaScript dans un contenu de fichier de script qui est injecté à l'aide d':
chrome.tabs.executeScript(tab.id, {file: "content.js"});
Vous devez vous connecter pour publier un commentaire.
Il n'y a pas une telle chose comme "passer un paramètre à un fichier".
Ce que vous peut faire est d'insérer un contenu script avant l'exécution du fichier, ou en envoyant un message après insérer le fichier. Je vais vous montrer un exemple de ces méthodes distinctes ci-dessous.
Définir les paramètres avant l'exécution du fichier JS
Si vous souhaitez définir des variables avant d'insérer le fichier, il suffit de nid
chrome.onglets.executeScript
appels:Si la variable n'est pas aussi simple, alors je vous recommande d'utiliser
JSON.stringify
de faire tourner un objet dans une chaîne de caractères:Avec la méthode précédente, les variables peuvent être utilisées dans
content.js
de la manière suivante:Définir les paramètres après l'exécution du fichier JS
La méthode précédente peut être utilisée pour définir les paramètres après le fichier JS. Au lieu de définir les variables directement dans la portée globale, vous pouvez utiliser le la transmission de message de l'API pour passer des paramètres:
Dans le contenu du script (
content.js
), vous pouvez écouter ces messages à l'aide de lachrome.moment de l'exécution.onMessage
événement, et de gérer le message:config.somebigobject
. Notez que "somebigobject" peut être n'importe quoi, je voulais juste montrer comment faire cela en général, et par le choix d'un improbable nom comme "somebigobject", j'ai voulu transmettre le message que vous pouvez mettre ce que vous voulez sur cet objet.chrome.runtime.onMessage.addListener
?window.onmessage
événement est déclenché par l'appel dewindow.postMessage
. Un contenu de script peut appeler cette méthode, mais la page sera également notifiée, ce qui peut ne pas être ce que vous voulez.Il y a cinq façons de transmettre des données à un script contenu injecté avec
onglets.executeScript()
(MDN):chrome.le stockage.local
(MDN) pour transmettre les données (défini avant l'injection de votre script).document_start
, sans la nécessité pour le contenu du script pour exécuter une requête asynchrone.chrome.le stockage.onChanged
(MDN) dans votre contenu script à écouter le fond de script pour définir une valeur à l'aidechrome.le stockage.locaux.set()
(MDN).Utilisation
chrome.storage.local
(défini avant l'exécution de votre script)À l'aide de cette méthode maintient l'exécution de paradigme que vous utilisez d'injecter un script qui exécute une fonction, puis se ferme. Il n'y a pas le problème de sécurité potentiel d'utilisation d'une valeur dynamique pour construire l'exécution de code, ce qui est fait dans la deuxième option ci-dessous.
De votre popup script:
chrome.le stockage.locaux.set()
(MDN).chrome.storage.local.set()
, appelonglets.executeScript()
(MDN).À partir de votre contenu script:
chrome.le stockage.locaux.get()
(MDN).storage.local
(suppression de la clé avec:chrome.le stockage.locaux.remove()
(MDN)).Voir: Notes 1 & 2.
Injecter du code avant votre script pour définir une variable
Avant l'exécution de votre script, vous pouvez injecter du code qui définit une variable dans le script contenu contexte qui votre script principal peut alors utiliser:
Problème de sécurité:
Les utilisations suivantes
"'" + JSON.stringify().replace(/\\/g,'\\\\').replace(/'/g,"\\'") + "'"
pour encoder les données dans le texte qui sera approprié JSON lorsqu'il est interprété comme du code, avant de les mettre dans lecode
chaîne. Le.replace()
méthodes sont nécessaires pour Un) ont correctement le texte interprété comme une chaîne de caractères lorsqu'il est utilisé comme code, et B) citez aucune'
qui existent dans les données. Il utilise ensuiteJSON.parse()
pour renvoyer les données dans une chaîne de caractères dans votre contenu de script. Tout ce codage n'est pas strictement nécessaire, c'est une bonne idée que vous ne connaissez pas le contenu de la valeur que vous allez envoyer le contenu du script. Cette valeur pourrait facilement être quelque chose qui pourrait corrompre le code à injecter (c'est à dire que L'utilisateur peut utiliser'
et/ou"
dans le texte, ils sont entrés). Si vous ne le faites pas, d'une certaine façon, d'échapper à la valeur, il y a un trou de sécurité qui pourrait entraîner l'exécution d'un code arbitraire.De votre popup script:
chrome.onglets.executeScript()
(MDN), appeltabs.executeScript()
afin d'injecter votre script (Note:tabs.executeScript()
va exécuter les scripts dans l'ordre dans lequel vous appeleztabs.executeScript()
, tant qu'ils ont la même valeur pourrunAt
. Ainsi, en attente pour le rappel de la petitecode
n'est pas strictement nécessaire).À partir de votre contenu script:
Voir: les Notes 1, 2, & 3.
Utilisation la transmission de message(MDN)(envoyer des données après contenu du script est injecté)
Cela nécessite de votre contenu code de script pour installer un écouteur pour un message envoyé par le pop-up, ou peut-être l'arrière-plan de script (si l'interaction avec l'INTERFACE utilisateur provoque le popup pour fermer). C'est un peu plus complexe.
De votre popup script:
onglets.query()
(MDN).onglets.executeScript()
(MDN)tabs.executeScript()
, utilisezonglets.sendMessage()
(MDN)(ce qui nécessite de connaître latabId
), pour envoyer les données sous forme de message.À partir de votre contenu script:
chrome.moment de l'exécution.onMessage.addListener()
(MDN).runtime.onMessage
auditeur#3.2 est facultatif. Vous pouvez garder votre code actif en attente pour un autre message, mais cela allait changer le paradigme que vous utilisez à un endroit où vous chargez votre code et il reste résident d'attente pour les messages pour lancer des actions.
Voir: Notes 1 & 2.
Remarque 1: à l'Aide de
Array.à partir de()
est très bien si vous ne le faites pas beaucoup de temps et sont à l'aide d'un la version de votre navigateur qui l'a (Chrome >= version 45, Firefox >= 32). Dans Chrome et Firefox,Array.à partir de()
est lent par rapport à d'autres méthodes d'obtenir un tableau à partir d'une NodeList. Pour une plus rapide, plus compatible conversion d'un Tableau, vous pouvez utiliser leasArray()
code dans cette réponse. La deuxième version deasArray()
fourni dans la réponse est également plus robuste.Note 2: Si vous êtes prêt à limiter votre code pour la version Chrome >= 51 ou Firefox version >= 50, Chrome a un
forEach()
méthode pour Élément nodelists de v51. Ainsi, vous n'avez pas besoin de convertir un tableau. De toute évidence, vous n'avez pas besoin de convertir un Tableau si vous utilisez un autre type de boucle.Note 3: Alors que je l'ai déjà utilisé cette méthode (à injecter un script avec la valeur de la variable) dans mon code, je me suis rappelé que je devrais avoir inclus ici lors de la lecture de cette réponse.
runAt
) les scripts sont injectés dans l'ordretabs.executeScript()
est appelé (Chrome & Firefox). Je ne me souviens pas si j'ai regardé le code source à la fois de vérifier. Un aspect important de cette est que injectés scripts viennent de l'intérieur de votre extension, pas de ressources réseau (où la plupart des async retard serait). Vous avez raison qu'il n'est pas garanti dans la documentation, c'est pourquoi je l'ai écrit telle qu'elle n'en fait attendre letabs.executeScript()
de rappel pour injecter le deuxième, noncode:
script.tabs.executeScript()
est exécuté, mais serait, il est peu probable qu'il ne serait pas dans cet ordre. Par exemple:tabs.executeScript()
probablement entre dans un message demandant à l'injection dans un message de la file d'attente pour être envoyé à la bonne gestion de processus, le contenu. Une fois reçu dans ce processus, il allait entrer dans une file d'attente pour injection (séparée de la file d'attente parrunAt
, ou, au moins, organisée parrunAt
), ou être traitées immédiatement (par exemple, pourcode:
qui est immédiatement disponible). etc.code:
script est disponible immédiatement (n'a même pas besoin d'être récupérées à partir de l'intérieur de votre extension (c'est à dire du disque ou de mémoire cache)). Cela signifie qu'il est encore plus susceptibles d'être injecté avant l'autre script. Cependant, l'essai je n'ai indiqué que, même pour plusieurs (mêmerunAt
) les scripts récupérés à partir de l'intérieur de l'extension, les scripts ont été injectés dans l'ordretabs.executeScript()
est appelé. Encore une fois, il n'est pas garanti, mais ça marche au moins 99%+ du temps. Mais, cela ne signifie pas que vous ne devriez pas attendre pour le rappel, lorsque vous avez une dépendance matérielle.