从站点调用Chrome扩展的后台功能 [英] Call background function of Chrome extension from a site

查看:87
本文介绍了从站点调用Chrome扩展的后台功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



想象一下 http://www.example.com/test.html 包含:

 <脚本> 
hello();
< / script>

我的后台页面包含 hello function:

 函数hello(){
alert(test);
}

如何确保Chrome扩展程序的后台页面 test.html 调用 hello();

调用> hello >

解决方案

在网页能够调用背景页面的函数之前,需要解决以下问题:


  1. 能够从网页中使用 hello(); 。这是通过使用内容脚本注入一个定义 hello 的脚本。注入的函数使用自定义事件或 postMessage 与内容脚本进行通信。

  2. 内容脚本需要与后台进行通信。这是通过 chrome.runtime.sendMessage

  3. 发送来自后台的回复页面( sendMessage / onMessage ,见下文)。

  4. 脚本,创建自定义事件或使用 postMessage 向网页发送消息。

  5. 在网页中处理此消息。

所有这些方法都是异步的,必须通过回调函数来实现。



这些步骤需要仔细设计。这是一个实现上述所有步骤的通用实现。你需要知道的实现:


  • 在要注入的代码中,使用 sendMessage sendMessage(< mixed message> [,< function callback>])方法在需要联系内容脚本时使用。 code>



contentscript.js

  //随机唯一名称,用于最小化冲突:
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){
//注意:这个函数被序列化并且运行在页面的上下文中
//页面函数的开始
window.hello = function(string){
sendMessage({
type:'sayhello',
data:string
},function(response){
alert('Background说:'+ response);
});
};

//结束你的逻辑,开始执行消息传递:
function sendMessage (message,callback){
var transporter = document.createElement('dummy');
// Handles reply:
transporter.addEventListener(reply_event_name,function(event){
var this result = this.getAttribute('result');
if(this.parentNode)this.parentNode.removeChild(this);
//清理完毕后,根据需要发送回调函数:
如果(类型callback =='function'){
result = JSON.parse(result);
回调(结果);
}
});
//通知内容脚本的功能
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); $'$'$'$'$'$'$'$'$'$'$'$'$'$'$'$'$'$'$'$'''') ;';
document.documentElement.appendChild(s);
s.parentNode.removeChild(s);


//处理/发送页面消息:
document.addEventListener(EVENT_FROM_PAGE,function(e){
var transporter = e.target;
if(transporter){
var request = JSON.parse(transporter.getAttribute('data'));
//处理示例:将消息发送到后台并等待回复
chrome。 runtime.sendMessage({
type:'page',
request:request
},function(data){
//接收到来自后台的消息,传递给页面
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;
//简单示例:从扩展的本地存储获取数据
var result = localStorage.getItem('whatever');
//将结果返回给内容脚本
sendResponse(result);
}
});

如果没有清单文件,Chrome扩展程序并不完整,所以这里是清单.json 我用来测试答案的文件:

  {
name :
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
}]
}

此扩展程序已在 http://jsfiddle.net/jRaPj/show/ (包含 hello(); ,如问题所示),并显示一个对话框说Background said:null。

打开背景页面,使用 localStorage.setItem('whatever','Hello!'); 看到邮件正确更改。


I am looking for a function inside a webpage te activate a chrome extension.

Imagine that http://www.example.com/test.html contains:

<script>
hello();
</script>

And my background page contains the definition of the hello function:

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

How can I make sure that the Chrome extension's background page's hello is called when test.html calls hello();?

解决方案

Before a web page is able to call a background page's function, the following problems need to be solved:

  1. Be able to use hello(); from a web page. This is done by injecting a script defining hello using Content scripts. The injected function communicates with the content script using a custom event or postMessage.
  2. The content script needs to communicate with the background. This is implemented through chrome.runtime.sendMessage.
    If the web page needs to receive a reply as well:
  3. Send a reply from the background page (sendMessage / onMessage, see below).
  4. In the content script, create a custom event or use postMessage to send a message to the web page.
  5. In the web page, handle this message.

All of these methods are asynchronous, and have to be implemented through callback functions.

These steps need to be designed carefully. Here's a generic implementation which implements all of the above steps. What you need to know about the implementation:

  • In the code-to-be-injected, use the sendMessage method whenever the content script need to be contacted.
    Usage: 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);
    }
});

A Chrome extension is not complete without a manifest file, so here's the manifest.json file which I used to test the answer:

{
    "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"
    }]
}

This extension was tested at http://jsfiddle.net/jRaPj/show/ (containing hello(); as seen in the question), and shows a dialog saying "Background said: null".
Open the background page, use localStorage.setItem('whatever', 'Hello!'); to see that the message is correctly changed.

这篇关于从站点调用Chrome扩展的后台功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆