Extension Chrome comment envoyer des données du script de contenu à popup.html

Je sais que cela a été demandé dans de nombreux postes, mais honnêtement, je ne les ai pas. Je suis nouveau sur JavaScript, Chrome Extensions et tout et j'ai cette classe. J'ai donc besoin de créer un plugin qui contiendrait des objets DOM sur une page donnée en utilisant Cross Domain Requests. J'ai été en mesure de réaliser jusqu'à présent avec les API de l'extension Chrome. Maintenant, le problème est que je dois afficher les données sur ma page popup.html à partir du fichier contentScript.js. Je ne sais pas comment faire, j'ai essayé de lire la documentation, mais la messagerie en chrome, je ne peux pas comprendre ce qu'il faut faire.

Voici le code jusqu'à présent.

Manifest.json

{ "manifest_version":2, "name":"Dom Reader", "description":"Counts Dom Objects", "version":"1.0", "page_action": { "default_icon":"icon.png", "default_title":"Dom Reader", "default_popup":"popup.html" }, "background":{ "scripts":["eventPage.js"], "persistent":false }, "content_scripts":[ { "matches":["http://pluralsight.com/training/Courses/*", "http://pluralsight.com/training/Authors/Details/*", "https://www.youtube.com/user/*", "https://sites.google.com/site/*", "http://127.0.0.1:3667/popup.html"], "js":["domReader_cs.js","jquery-1.10.2.js"] //"css":["pluralsight_cs.css"] } ], "permissions":[ "tabs", "http://pluralsight.com/*", "http://youtube.com/*", "https://sites.google.com/*", "http://127.0.0.1:3667/*" ] 

Popup.html

 <!doctype html> <html> <title> Dom Reader </title> <script src="jquery-1.10.2.js" type="text/javascript"></script> <script src="popup.js" type="text/javascript"></script> <body> <H1> Dom Reader </H1> <input type="submit" id="readDom" value="Read DOM Objects" /> <div id="domInfo"> </div> </body> </html> 

EventPage.js

 var value1,value2,value3; chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) { if (request.action == "show") { chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) { chrome.pageAction.show(tabs[0].id); }); } value1 = request.tElements; }); 

Popup.js

 $(function (){ $('#readDom').click(function(){ chrome.tabs.query({active: true, currentWindow: true}, function (tabs){ chrome.tabs.sendMessage(tabs[0].id, {action: "readDom"}); }); }); }); 

ContentScript

 var totalElements; var inputFields; var buttonElement; chrome.runtime.onMessage.addListener(function (request, sender, sendResponse){ if(request.action == "readDom"){ totalElements = $("*").length; inputFields = $("input").length; buttonElement = $("button").length; } }) chrome.runtime.sendMessage({ action: "show", tElements: totalElements, Ifields: inputFields, bElements: buttonElement }); 

Toute aide serait appréciée et évitez tout bêtisement que j'ai fait 🙂

Bien que vous êtes certainement dans la bonne direction (et en fait assez proche de la fin), il existe plusieurs (imo) mauvaises pratiques dans votre code (par exemple, en injectant une bibliothèque entière (jquery) pour une tâche aussi insignifiante, déclarant des autorisations inutiles, faisant du superflus Appels vers des méthodes API etc.).
Je n'ai pas testé votre code moi-même, mais d'un aperçu rapide, je crois que la correction des éléments suivants pourrait entraîner une solution de travail (mais pas très proche de l'optimum):

  1. Dans manifest.json : Modifiez l'ordre des scripts de contenu, en mettant jquery en premier. Selon les documents pertinents :

    "Js" […] La liste des fichiers JavaScript à injecter dans les pages correspondantes. Ceux-ci sont injectés dans l'ordre qu'ils apparaissent dans ce tableau.

    (L'accent est mis)

  2. Dans contentscript.js : Déplacez le bloc chrome.runtime.sendMessage ({…}) dans le rappel d' onMessage .


Cela dit, voici mon approche proposée:

Flux de contrôle:

  1. Un script de contenu est injecté dans chaque page correspondant à certains critères.
  2. Une fois injecté, les scripts de contenu envoient un message à la page d'événement (page d'arrière-plan non persistante) et la page d'événement attache une page = action à l'onglet.
  3. Dès que la popup de l'action de la page est chargée, elle envoie un message au script de contenu, en demandant l'information dont elle a besoin.
  4. Le script de contenu traite la requête et répond pour que la fenêtre contextuelle puisse afficher les informations.

Structure de l'annuaire:

  root-directory/ |_____img |_____icon19.png |_____icon38.png |_____manifest.json |_____background.js |_____content.js |_____popup.js |_____popup.html 

Manif.json:

 { "manifest_version": 2, "name": "Test Extension", "version": "0.0", "offline_enabled": true, "background": { "persistent": false, "scripts": ["background.js"] }, "content_scripts": [{ "matches": ["*://*.stackoverflow.com/*"], "js": ["content.js"], "run_at": "document_idle", "all_frames": false }], "page_action": { "default_title": "Test Extension", //"default_icon": { // "19": "img/icon19.png", // "38": "img/icon38.png" //}, "default_popup": "popup.html" } // No special permissions required... //"permissions": [] } 

Background.js:

 chrome.runtime.onMessage.addListener(function (msg, sender) { // First, validate the message's structure if ((msg.from === 'content') && (msg.subject === 'showPageAction')) { // Enable the page-action for the requesting tab chrome.pageAction.show(sender.tab.id); } }); 

Content.js:

 // Inform the background page that // this tab should have a page-action chrome.runtime.sendMessage({ from: 'content', subject: 'showPageAction' }); // Listen for messages from the popup chrome.runtime.onMessage.addListener(function (msg, sender, response) { // First, validate the message's structure if ((msg.from === 'popup') && (msg.subject === 'DOMInfo')) { // Collect the necessary data // (For your specific requirements `document.querySelectorAll(...)` // should be equivalent to jquery's `$(...)`) var domInfo = { total: document.querySelectorAll('*').length, inputs: document.querySelectorAll('input').length, buttons: document.querySelectorAll('button').length }; // Directly respond to the sender (popup), // through the specified callback */ response(domInfo); } }); 

Popup.js:

 // Update the relevant fields with the new data function setDOMInfo(info) { document.getElementById('total').textContent = info.total; document.getElementById('inputs').textContent = info.inputs; document.getElementById('buttons').textContent = info.buttons; } // Once the DOM is ready... window.addEventListener('DOMContentLoaded', function () { // ...query for the active tab... chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) { // ...and send a request for the DOM info... chrome.tabs.sendMessage( tabs[0].id, {from: 'popup', subject: 'DOMInfo'}, // ...also specifying a callback to be called // from the receiving end (content script) setDOMInfo); }); }); 

Popup.html:

 <!DOCTYPE html> <html> <head> <script type="text/javascript" src="popup.js"></script> </head> <body> <h3 style="font-weight:bold; text-align:center;">DOM Info</h3> <table border="1" cellpadding="3" style="border-collapse:collapse;"> <tr> <td nowrap>Total number of elements:</td> <td align="right"><span id="total">N/A</span></td> </tr> <tr> <td nowrap>Number of input elements:</td> <td align="right"><span id="inputs">N/A</span></td> </tr> <tr> <td nowrap>Number of button elements:</td> <td align="right"><span id="buttons">N/A</span></td> </tr> </table> </body> </html> 

Vous pouvez utiliser localStorage pour cela. Vous pouvez stocker toutes les données dans un format de table de hash dans la mémoire du navigateur, puis y accéder à tout moment. Je ne suis pas certain si nous pouvons accéder à localStorage à partir du script de contenu (il a été bloqué avant), essayez de le faire par vous-même. Voici comment le faire via votre page d'arrière-plan (je passe d'abord les données du script de contenu à la page d'arrière-plan, puis enregistrez-la dans localStorage):

Dans contentScript.js:

 chrome.runtime.sendMessage({ total_elements: totalElements // or whatever you want to send }); 

Dans eventPage.js (votre page d'arrière-plan):

 chrome.runtime.onMessage.addListener( function(request, sender, sendResponse){ localStorage["total_elements"] = request.total_elements; } ); 

Ensuite, vous pouvez accéder à cette variable dans popup.js avec localStorage ["total_elements"].

Peut-être que vous pouvez accéder à localStorage directement à partir du script de contenu dans les navigateurs modernes. Ensuite, vous n'avez pas besoin de transmettre les données dans votre page d'arrière-plan.

Bonne lecture sur localStorage: http://diveintohtml5.info/storage.html