2017-09-15 6 views
0

Je suis en train de créer une extension Chrome et lorsque je clique sur l'icône de la barre d'outils, j'exécute background.js, et en background.js j'exécute le script d'exécution. Comme ceci:Accéder à des variables de site Web avec un script injecté via background.js

chrome.tabs.executeScript(null, { file: "libs/jquery.min.js" }, function() { 
    chrome.tabs.executeScript(null, { file: "scripts/myScript.js" }) 
}); 

En myScript.js, je peux confirmer qu'il a exécuté jQuery et en cours d'exécution trop mon script.


MyScript.js:

console.log('test'); 

$(document).ready(function() { 
    console.log('jQuery test'); 
}) 

Ils travaillent tous les deux


A ce moment, je suis en train de réaliser une variable qui se trouve dans la page web (pas écrit par moi) disons que c'est var helloWorld = "the content".

Si j'essaye dans la console (outils de dev), console.log(helloWorld), cela fonctionne. Cependant, si j'essaie de myScript.js, il est dit:

$(document).ready(function() { 
    console.log(helloWorld) 

    setTimeout(function() { 
     console.log(helloWorld) 
    }, 1500) 
}) 

Uncaught ReferenceError: helloWorld is not defined


Je l'ai vu une solution de contournement pour l'approche de script de contenu, mais je ne pouvais pas le faire fonctionner à l'approche ExecuteScript. Comment puis-je accéder à la variable helloWorld à l'intérieur de myScript.js?


J'ai essayé d'utiliser l'approche de Predator. Voici les codes:

injected.js:

chrome.runtime.sendMessage("njfhnpgecmbmbipcjpkkglbkpcbjammb", {varName: "test"}); 
// I tried returning a string first 

background.js

chrome.tabs.executeScript(null, { file: "libs/jquery.min.js" }, function() { 
    chrome.tabs.executeScript(null, { file: "scripts/myScript.js" }) 
}); 

chrome.runtime.onMessageExternal.addListener(function(message, sender, sendResponse){ 
    console.log(message.varName); 
    if(message.varName !== undefined){ 
     console.log(message.varName); 
    } 
}); 

manifeste:

"background": { 
    "scripts": ["scripts/background.js"], 
    "persistent": true 
}, 

selon votre première réponse, myScript.js:

$(document).ready(function() { 
    setTimeout(function() { 
     var s = document.createElement('script'); 

     s.src = chrome.extension.getURL('scripts/fetcher.js'); 
     s.onload = function() { 
      this.remove(); 
     }; 
     (document.head || document.documentElement).appendChild(s); 
    }, 500) 
}) 

selon votre réponse à jour, myScript.js:

function exec(fn) { 
    var script = document.createElement('script'); 
    script.setAttribute("type", "application/javascript"); 
    script.textContent = '(' + fn + ')();'; 
    document.body.appendChild(script); //run the script 
    document.body.removeChild(script); //clean up 
} 

background.js est ne rattrapent pas le message

+0

Je recommande la lecture (https://developer.chrome.com/extensions/messaging) [Message Passing]. – PredatorIWD

+0

Comment puis-je lire les données sur le site tiers DOM, de sorte que je peux utiliser le passage de messages? J'ai utilisé Message Passing avant de communiquer entre mes scripts (background.js et content_script.js) mais je suis resté à la première partie de la question (lecture de la variable js sur le site tiers DOM) – senty

+0

Vous injectez le script de contenu, récupérez la variable puis envoyez-le à votre script de fond à traiter. – PredatorIWD

Répondre

0

Votre script de contenu est exécuté dans un contexte distinct, ce qui signifie qu'il ne peut pas accéder à la portée globale de la page Web. Cependant, je ne réussi auparavant à contourner ce problème en code via l'injection

location.href = "javascript: /* some messaging code */"; 

probablement pas la meilleure pratique, mais cela a fonctionné pour moi (et il pourrait y avoir nouvelles API qui vous permet de faire sans cela.)

+0

Pouvez-vous s'il vous plaît développer votre approche plus?Je ne pouvais pas comprendre comment exactement vous avez obtenu les données et l'avez passé. Je serais reconnaissant – senty

0

Comme je l'ai dit plus haut dans les commentaires après l'injection de la fonction ou le code du script de contenu à la page du site que vous pouvez envoyer un message à l'extérieur de cette page aux background.js de votre poste. Après quoi, vous pouvez avoir ce code pour écouter ces messages externes et y répondre ou utiliser la valeur qui a été envoyée.

chrome.runtime.onMessageExternal.addListener(function(message, sender, sendResponse){ 

    if(message.varName !== undefined){ 
     //process the info 
    } 

}); 

Edit: premier essai cela et si cela ne fonctionne pas lire plus bas:

Ajouter ce au fond de votre manifest.json et essayez à nouveau:

"externally_connectable": { 
    "matches": [ "https://theSiteWhereYouAreInjectinTheCode.com/*" ] 
} 

Si elle encore didn Ne travaillez pas après avoir essayé d'ajouter cette fonction à votre content script qui va injecter ce code sur la page Web.

//Injects functions directly into the dom 
function exec(fn) { 
    var script = document.createElement('script'); 
    script.setAttribute("type", "application/javascript"); 
    script.textContent = '(' + fn + ')();'; 
    document.body.appendChild(script); //run the script 
    document.body.removeChild(script); //clean up 
} 

Et puis appelez là comme ceci:

exec(function(){ 
    chrome.runtime.sendMessage("njfhnpgecmbmbipcjpkkglbkpcbjammb", {varName: "helloWorld"}); 
}); 
+0

@senty Dans votre manifeste à '" background "', avez-vous '' persist '' '' true'? – PredatorIWD

+0

Je viens de l'ajouter. Il ne retourne toujours rien. Je ne pouvais pas l'attraper dans 'background.js'. Dans la méthode sendMessage du script injecté, j'ai essayé de mettre en place un callback, et il envoie en effet le message, mais je ne pouvais pas l'obtenir dans background.js comme je l'ai dit – senty

+0

@senty Pouvez-vous mettre à jour le message avec le code exact? 'background.js',' manifest.json' et le code que vous injectez dans la page Web, ce qui inclut l'envoi de ce message externe? – PredatorIWD