Fonction d'arrière-plan d'appel de l'extension Chrome à partir d'un site

Je recherche une fonction dans une page Web pour activer une extension chrome.

Imaginez que http://www.example.com/test.html contient:

<script> hello(); </script> 

Et ma page d'arrière-plan contient la définition de la fonction hello :

 function hello() { alert("test"); } 

Comment puis-je m'assurer que le hello la page d'arrière-plan de l'extension Chrome est appelé lorsque test.html appelle hello(); ?

Avant qu'une page Web puisse appeler une fonction de la page d'arrière-plan, les problèmes suivants doivent être résolus:

  1. Possibilité d'utiliser hello(); À partir d'une page Web. Cela se fait en injectant un script définissant hello utilisant les scripts de contenu. La fonction injectée communique avec le script de contenu en utilisant un événement personnalisé ou postMessage .
  2. Le script de contenu doit communiquer avec l'arrière-plan. Ceci est implémenté via chrome.runtime.sendMessage .
    Si la page Web doit également recevoir une réponse:
  3. Envoyez une réponse à partir de la page d'arrière-plan ( sendMessage / onMessage , voir ci-dessous).
  4. Dans le script de contenu, créez un événement personnalisé ou utilisez postMessage pour envoyer un message à la page Web.
  5. Dans la page Web, manipulez ce message.

Toutes ces méthodes sont asynchrones et doivent être mises en œuvre par des fonctions de rappel.

Ces étapes doivent être conçues avec soin. Voici une implémentation générique qui implémente toutes les étapes ci-dessus. Ce que vous devez savoir sur la mise en œuvre:

  • Dans le code à être injecté, utilisez la méthode sendMessage chaque fois que le script de contenu doit être contacté.
    Utilisation: sendMessage(<mixed message> [, <function callback>])

Contentscript.js

 // Random unique name, to be used to minimize conflicts: var EVENT_FROM_PAGE = '__rw_chrome_ext_' + new Date().getTime(); var EVENT_REPLY = '__rw_chrome_ext_reply_' + new Date().getTime(); var s = document.createElement('script'); s.textContent = '(' + function(send_event_name, reply_event_name) { // NOTE: This function is serialized and runs in the page's context // Begin of the page's functionality window.hello = function(string) { sendMessage({ type: 'sayhello', data: string }, function(response) { alert('Background said: ' + response); }); }; // End of your logic, begin of messaging implementation: function sendMessage(message, callback) { var transporter = document.createElement('dummy'); // Handles reply: transporter.addEventListener(reply_event_name, function(event) { var result = this.getAttribute('result'); if (this.parentNode) this.parentNode.removeChild(this); // After having cleaned up, send callback if needed: if (typeof callback == 'function') { result = JSON.parse(result); callback(result); } }); // Functionality to notify content script var event = document.createEvent('Events'); event.initEvent(send_event_name, true, false); transporter.setAttribute('data', JSON.stringify(message)); (document.body||document.documentElement).appendChild(transporter); transporter.dispatchEvent(event); } } + ')(' + JSON.stringify(/*string*/EVENT_FROM_PAGE) + ', ' + JSON.stringify(/*string*/EVENT_REPLY) + ');'; document.documentElement.appendChild(s); s.parentNode.removeChild(s); // Handle messages from/to page: document.addEventListener(EVENT_FROM_PAGE, function(e) { var transporter = e.target; if (transporter) { var request = JSON.parse(transporter.getAttribute('data')); // Example of handling: Send message to background and await reply chrome.runtime.sendMessage({ type: 'page', request: request }, function(data) { // Received message from background, pass to page var event = document.createEvent('Events'); event.initEvent(EVENT_REPLY, false, false); transporter.setAttribute('result', JSON.stringify(data)); transporter.dispatchEvent(event); }); } }); 

Background.js

 chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) { if (message && message.type == 'page') { var page_message = message.message; // Simple example: Get data from extension's local storage var result = localStorage.getItem('whatever'); // Reply result to content script sendResponse(result); } }); 

Une extension Chrome n'est pas complète sans un fichier manifeste, alors voici le fichier manifest.json que j'ai utilisé pour tester la réponse:

 { "name": "Page to background and back again", "version": "1", "manifest_version": 2, "background": { "scripts": ["background.js"] }, "content_scripts": [{ "matches": ["http://jsfiddle.net/jRaPj/show/*"], "js": ["contentscript.js"], "all_frames": true, "run_at": "document_start" }] } 

Cette extension a été testée à l' adresse http://jsfiddle.net/jRaPj/show/ (contenant hello(); comme on l'a vu dans la question), et montre une boîte de dialogue indiquant "Background said: null".
Ouvrez la page d'arrière-plan, utilisez localStorage.setItem('whatever', 'Hello!'); Pour voir que le message est correctement modifié.

Non, avec votre code ci-dessus en raison de l' architecture des pages de fond

Oui avec des scripts de contenu

Démonstration à l'aide de scripts de contenu

Manifest.json

Enregistrement de scripts de contenu myscripts.js

 { "name": "NFC", "description": "NFC Liken", "version": "0.1", "manifest_version": 2, "permissions": ["tabs", "http://*/", "https://*/"], "content_scripts": { "matches": "http://www.example.com/*", "js": [ "myscript.js"] }, "browser_action": { "default_icon": "sync-icon.png", "default_title": "I Like I Tag" } } 

Faites-moi savoir si vous avez besoin de plus d'informations.

Il existe une solution complète pour envoyer des messages de pages Web à l'extension

mainfest.json

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

Page web:

 // The ID of the extension we want to talk to. var editorExtensionId = "abcdefghijklmnoabcdefhijklmnoabc"; // Make a simple request: chrome.runtime.sendMessage(editorExtensionId, {openUrlInEditor: url}, function(response) { if (!response.success) handleError(url); }); 

Extension du script de fond:

 chrome.runtime.onMessageExternal.addListener( function(request, sender, sendResponse) { if (sender.url == blacklistedWebsite) return; // don't allow this web page access if (request.openUrlInEditor) openUrl(request.openUrlInEditor); });