如何通过扩展为JavaScript代码提供额外的功能? [英] How do I provide an extra function to javascript code through an extension?

查看:105
本文介绍了如何通过扩展为JavaScript代码提供额外的功能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想写一个扩展,它执行以下操作:


  • 定义一个自定义函数

  • 允许来自Internet的Javascript代码加载运行此功能



该函数应该作为参数一个事件监听器。基本上,如下所示:

  newApiFunctionDefinedInExtension(function(responseHeaders){
console.log(Headers arrived! responseHeaders);
};

然后使用 chrome.webRequest ,我的扩展(首先使 newApiFunctionDefinedInExtension 可用)将会调用每次从网络接收到响应标头时,该监听器(位于本地加载的页面中)。



我是Chrome扩展的新手,无法找到实现此目的的方法。知道:


  • 如何使一个模块中定义的函数可用于已加载页面的作用域

  • 如何制作这样一个EventEmitter - 是否可以扩展一个构造函数类?



我的目标很简单:加载的页面应该定义一个函数,并且该函数应该被称为前夕每个webRequest事件都会收到一个请求的信息,其中包括一个或多个webRequest事件的ID

因此,假设选项卡中存在 note 1 ,您可以使用以下流程:

  // background.js 
chrome.webRequest.onHeadersReceived.addListener(function(details){
if(details.tabId == -1)
return; //不涉及任何标签
chrome.tabs.sendMessage(details.tabId,{
responseHeaders:details.responseHeaders
});
},{
url:['*:// * / *'],//例如所有http(s)网址。查看匹配模式docs
// types:['image'] //例如,默认为** all **请求类型
},['responseHeaders']);

然后,在内容脚本在清单文件中声明<

  // contentscript.js 
chrome.runtime.onMessage.addListener(function(message){
//假设所有来自后台的消息都是用于页面的:
document.dispatchEvent(new CustomEvent('my-extension-event' ,{
detail:message
}));
});

完成此操作后,您的网页可以接收这些事件,如下所示:

  document.addEventListener('my-extension-event',function(event){
var message = event.detail;
if(message.responseHeaders){
//做一些响应标题
}
});

如果您想将抽象置于顶层(例如实现自定义EventEmitter),那么您需要在主体中注入脚本执行环境,并在那里声明自定义API。



note 1 。为了简单起见,我认为该选项卡存在。实际上,键入main_frame(和sub_frame),因为该页面尚未呈现。如果您想获得顶级/框架文档的响应标题,那么您需要将响应标头临时存储在背景页面中的某些数据结构(例如队列/字典)中,并且每当将数据发送到内容脚本时该脚本已准备就绪。

这可以通过使用 <$内容脚本中的c $ c> chrome.runtime.sendMessage 发送消息到后台页面。然后,无论何时加载页面并且内容脚本已准备就绪,后台页面都可以使用 sendResponse 来传递任何排队的消息。


I want to write an extension that does the following:

  • Defines a custom function
  • Allows Javascript code loaded from the Internet to run such a function

The function should take as a parameter an event listener. Basically, something like:

newApiFunctionDefinedInExtension( function( responseHeaders ){
  console.log("Headers arrived!", responseHeaders );
} ; 

Then using chrome.webRequest, my extension (which made newApiFunctionDefinedInExtension available in the first place) will call the listener (in the locally loaded page) every time response headers are received from the network.

I am new to Chrome extensions and cannot find a way to make that happen. It would be great to know:

  • How to make a function defined in a module available to the loaded page's scope
  • How to make such an EventEmitter -- is there a constructor class I can extend?

My goal is simple: the loaded page should define a function, and that function should be called every time there is a network connection.

解决方案

Every webRequest event receives information about a request, including the ID of the originating tab.

So, assuming that the tab exists note 1, you can use the following flow:

// background.js
chrome.webRequest.onHeadersReceived.addListener(function(details) {
    if (details.tabId == -1)
        return; // Not related to any tab
    chrome.tabs.sendMessage(details.tabId, {
        responseHeaders: details.responseHeaders
    });
}, {
    urls: ['*://*/*'], // e.g. all http(s) URLs. See match patterns docs
    // types: ['image'] // for example, defaults to **all** request types
}, ['responseHeaders']);

Then, in a content script (declared in the manifest file), you take the message and pass it to the web page:

// contentscript.js
chrome.runtime.onMessage.addListener(function(message) {
    // Assuming that all messages from the background are meant for the page:
    document.dispatchEvent(new CustomEvent('my-extension-event', {
        detail: message
    }));
});

After doing that, your web page can just receive these events as follows:

document.addEventListener('my-extension-event', function(event) {
    var message = event.detail;
    if (message.responseHeaders) {
        // Do something with response headers
    }
});

If you want to put an abstraction on top (e.g. implementing a custom EventEmitter), then you need to inject a script in the main execution environment, and declare your custom API over there.

note 1. For simplicity, I assumed that the tab existed. In reality, that is never true for type "main_frame" (and "sub_frame"), because the page has not yet been rendered. If you want to get response headers for the top-level/frame documents, then you need to temporarily store the response headers in some data structure (e.g. a queue / dictionary) in the background page, and send the data to the content script whenever the script is ready.
This can be implemented by using chrome.runtime.sendMessage in the content script to send a message to the background page. Then, whenever a page has loaded and the content script is ready, the background page can use sendResponse to deliver any queued messages.

这篇关于如何通过扩展为JavaScript代码提供额外的功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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