62 votes

L'objet fenêtre peut-il être modifié à partir d'une extension Chrome ?

Je voudrais faire une extension Chrome qui fournit un nouvel objet à l'intérieur de window . Lorsqu'une page web est affichée dans un navigateur avec l'extension chargée, je voudrais que window.mything pour être disponible via Javascript. Le site window.mything aura quelques fonctions que je définirai dans l'extension, et ces fonctions devront être appelables à partir de console.log ou tout autre fichier Javascript lorsque la page est affichée dans un navigateur dont l'extension est activée.

J'ai pu injecter avec succès un fichier Javascript dans la page en utilisant une balise Contenu script :

var s = document.createElement("script"); 
s.src = chrome.extension.getURL("mything.js");
document.getElementsByTagName("head")[0].appendChild(s);

mything.js ressemble à ceci :

window.mything = {thing: true};
console.log(window);

A chaque fois qu'une page se charge, je vois l'ensemble de la page window comme je l'attends dans la console. Cependant, je ne peux pas interagir avec l'objet window.mything à partir de la console. Il semble que si le script injecté n'a pas vraiment modifié l'objet global de la console, il n'en est rien. window objet.

Comment puis-je modifier l'interface globale window à partir d'une extension Chrome ?

67voto

nynexman4464 Points 467

Vous ne pouvez pas, pas directement. De la contenu scripts documentation :

Cependant, les scripts de contenu ont certaines limites. Ils ne peuvent pas :

  • Utiliser les API chrome.* (sauf pour certaines parties de chrome.extension)
  • Utiliser des variables ou des fonctions définies par les pages de leur extension
  • Utiliser des variables ou des fonctions définies par des pages web ou par d'autres contenus scripts.

(accentuation ajoutée)

Le site window le contenu que script voit n'est pas le même. window que la page voit.

Vous pouvez cependant transmettre des messages via le DOM, en utilisant la fonction window.postMessage méthode. Votre page et le contenu script écoutent tous deux la méthode message et chaque fois que vous appelez window.postMessage de l'un de ces endroits, l'autre le recevra. Il y a un exemple de ce qui suit sur la page de documentation "Contenu scripts".

éditer : Vous pourriez potentiellement ajouter des méthodes à la page en injectant un script depuis le contenu script. Il ne serait toujours pas en mesure de communiquer en retour avec le reste de l'extension cependant, sans utiliser quelque chose comme postMessage mais vous pourriez au moins ajouter des choses à la page window

var elt = document.createElement("script");
elt.innerHTML = "window.foo = {bar:function(){/*whatever*/}};"
document.head.appendChild(elt);

26voto

Bruno Lemos Points 143

Après des heures à essayer différentes tentatives et à faire face à des problèmes de sécurité comme CORS, j'ai trouvé le moyen d'éditer le fichier window l'objet sur Chrome , Firefox y Safari . Vous devez utiliser des stratégies différentes pour chacun d'entre eux :

Chrome

  1. Ajoutez votre script à content_scripts .
  2. À l'intérieur de votre fichier script, ajoutez une balise script à la page et lui faire exécuter votre code personnalisé en ligne. Comme ceci :

    ;(function() { function script() { // your main code here window.foo = 'bar' }

    function inject(fn) { const script = document.createElement('script') script.text = (${fn.toString()})(); document.documentElement.appendChild(script) }

    inject(script) })()

Firefox

Sous Firefox, la solution ci-dessus ne fonctionne pas en raison d'un problème de type Content-Security-Policy erreur. Mais la solution de contournement suivante fonctionne, du moins pour l'instant :

  1. Ajouter 2 scripts à content_scripts par exemple inject.js y script.js

  2. Le site inject script obtiendra l'intégralité de l'information sur l'état de l'environnement. URL absolue de la script.js et le charger :

    ;(function() { const b = typeof browser !== 'undefined' ? browser : chrome

    const script = document.createElement('script') script.src = b.runtime.getURL('script.js') document.documentElement.appendChild(script) })()

  3. Votre script.js contiendra votre code principal :

    ;(function() { // your main code here window.foo = 'bar' })()

Safari

C'est très similaire à Firefox.

  1. Créez 2 fichiers javascript, par exemple inject.js y script.js

  2. Le site inject script obtiendra l'intégralité de l'information sur l'état de l'environnement. URL absolue de la script.js et le charger :

    ;(function() { const script = document.createElement('script') script.src = safari.extension.baseURI + 'script.js' document.documentElement.appendChild(script) })()

  3. Votre script.js contiendra votre code principal :

    ;(function() { // your main code here window.foo = 'bar' })()

Code source

Voir le code complet ici : https://github.com/brunolemos/simplified-twitter

15voto

Lucio Paiva Points 368

Comme d'autres l'ont souligné, les scripts contextuels ne s'exécutent pas dans le même contexte que celui de la page. window vous devez injecter du code dans la page.

Voici mon point de vue :

function codeToInject() {
    // Do here whatever your script requires. For example:
    window.foo = "bar";
}

function embed(fn) {
    const script = document.createElement("script");
    script.text = `(${fn.toString()})();`;
    document.documentElement.appendChild(script);
}

embed(codeToInject);

Propre et facile à utiliser. Tout ce que vous avez besoin d'exécuter dans le contexte de la page, mettez-le dans codeToInject() (vous pouvez l'appeler comme vous le préférez). Le site embed() se charge d'emballer votre fonction et de l'envoyer pour qu'elle soit exécutée dans la page.

¿Qué embed() consiste à créer un script dans la page et intégrer la fonction codeToInject() en tant que IIFE . Le navigateur exécutera immédiatement la nouvelle script dès qu'elle est ajoutée au document et votre code injecté s'exécutera dans le contexte de la page, comme prévu.

9voto

ztrat4dkyle Points 156

L'extension de chrome content_script s'exécute dans son propre contexte, distinct de celui de la fenêtre. Vous pouvez cependant injecter un script dans la page afin qu'il s'exécute dans le même contexte que la fenêtre de la page, comme ceci : Extension Chrome - récupération d'une variable globale à partir d'une page web

J'ai pu appeler des méthodes sur l'objet fenêtre et modifier les propriétés de la fenêtre en ajoutant essentiellement une fonction script.js au DOM de la page :

var s = document.createElement('script');
s.src = chrome.extension.getURL('script.js');
(document.head||document.documentElement).appendChild(s);
s.onload = function() {
    s.remove();
};

et créer des écouteurs d'événements personnalisés dans ce fichier script injecté :

document.addEventListener('_my_custom_event', function(e) {
  // do whatever you'd like! Like access the window obj
  window.myData = e.detail.my_event_data;
})

et l'envoi de cet événement dans le content_script :

var foo = 'bar'
document.dispatchEvent(new CustomEvent('_save_OG_Editor', {
  'detail': {
    'my_event_data': foo
  }
}))

ou vice versa ; répartir les événements dans script.js et les écouter dans le content_script de votre extension (comme le lien ci-dessus l'illustre bien).

Veillez simplement à ajouter votre script injecté dans les fichiers de votre extension, et ajoutez le chemin du fichier script à votre manifeste dans "web_accessible_resources" ou vous obtiendrez une erreur.

J'espère que cela aidera quelqu'un

6voto

Kevin H Points 41

Je me suis amusé avec ça. J'ai découvert que je peux interagir avec l'objet fenêtre du navigateur en intégrant mon javascript dans un appel à window.location=.

var myInjectedJs = "window.foo='This exists in the \'real\' window object';"
window.location = "javascript:" + myInjectedJs;

var myInjectedJs2 = "window.bar='So does this.';"
window.location = "javascript:" + myInjectedJs2;

Cela fonctionne, mais seulement pour la dernière instance de window.location qui a été définie. Si vous accédez à l'objet window du document, il aura une variable "bar" mais pas "foo".

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X