Chrome扩展之通信

Chrome扩展通信

chrome扩展的5种js

js类型介绍
popup单击插件图标后的弹窗中的js,由于单击图标打开popup,焦点离开又立即关闭,生命周期一般很短。
content-script与页面共享DOM,但是不共享JS,可访问部分chrome扩展API。
background权限最高,几乎可调用所有Chrome扩展API(除了devTools),且可以无限制跨域。生命周期最长,跟随浏览器开关。
injected-script通过DOM操作的方式向页面注入的一种JS,和原始页面共享js(即可访问原始页面变量,方法等),无法访问Chrome扩展API。
devtools每打开一个开发者工具窗口,都会创建devtools的页面的实例,F12窗口关闭,页面也随之关闭,故devtools的生命周期和devtools窗口是一致的。可访问一组特有的DevTools API(background都无权访问):chrome.devtools.panels(面板相关);chrome.devtools.inspectedWindow(获取被审查窗口的相关信息);chrome.devtools.network(获取有关网络请求信息)。

Chrome插件提供的2种额外的通信方式

  1. chrome.tabs.sendMessagechrome.runtime.sendMessage 用于简单的一次性请求;
  2. chrome.tabs.connectchrome.runtime.connect,用于长时效连接。

通信接口使用限制

inject-scriptcontent-scriptpopup-jsbackground
inject-script-window.postMessage--
content-scriptwindow.postMessage-chrome.runtime.sendMessage chrome.runtime.connectchrome.runtime.sendMessage chrome.runtime.connect
popup-js-chrome.tabs.sendMessage chrome.tabs.connect-chrome.runtime.sendMessage chrome.runtime.connect
background-js-chrome.tabs.sendMessage chrome.tabs.connectchrome.tabs.sendMessage chrome.tabs.connect-
devtools-jschrome.devtools.inspectedWindow.evalchrome.runtime.sendMessagechrome.runtime.sendMessage

chrome.runtime.onMessageExternal 接口用于扩展间通信,与chrome.tabs.sendMessage 用法类似。

一次性请求

一次性请求类似于HTTP请求,包含一次请求和一次返回,且如果接收方不在线,就会出现请求失败;

扩展程序(popup、background)向content-script一次性通信

//popup.js发送
function sendToContentScript(message, callback){
	chrome.tabs.query({active: true, currentWindow: true}, tabs => {
		chrome.tabs.sendMessage(tabs[0].id, message, callback);
	});
}
sendToContentScript({cmd:'test', value:'popup_to_content'}, res => {
	console.log(res)   *// {res:'content_to_popup'}*
} );

// content_script.js接收
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
	console.log(request)   *// {cmd:'test', value:'popup_to_content'}*
	if(request.cmd === 'content_to_bg'){
		sendResponse({res:'content_to_popup'})
	  // 若异步使用sendResponse,需添加return true*
	}
})

双方通信直接发送的都是JSON对象,不是JSON字符串,所以无需解析,很方便(当然也可以直接发送字符串)

content-script主动向扩展程序(background、popup)一次性通信

// content_script.js发送
chrome.runtime.sendMessage({cmd: 'test', value:'content_to_bg'}, res => {
	console.log(res);     //{res:'bg_to_content'}
});

// background.js接收
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
	console.log(request);   // {cmd: 'test', value:'content_to_bg'}
	sendResponse({res:'bg_to_content'})
});

注意事项

  • content_scriptspopup主动发消息的前提是popup处于打开状态,否则需要利用background作中转;
  • 使用chrome.runtime.sendMessage后无论是否需要回应,接收方都需调用sendReponse反馈,若不调用则发送方就会报错:
  • 如果backgroundpopup同时监听,那么它们都可以同时收到消息,但是只有一个可以sendResponse,一个先发送了,那么另外一个再发送就无效

页面脚本(包括inject-script)和content-script之间一次性通信

由于inject-script和content-script内均可获取到原始页面的window对象,故可通过window.postMessage来进行通信。该方法还可规避跨域的限制,可以在任意页面之间进行通信。

//inject-script
window.postMessage({cmd:"test",value:"inject_to_content"},"*")

//content-script
window.addEventListener("message", e => {
	console.log(e.data)    //{cmd:"test",value:"inject_to_content"}
})

长时效连接

长连类似 WebSocket,建立连接后会一直保持,双方可以随时互发消息。

chrome.tabs.connectchrome.runtime.connect 长时效连接通信示例

扩展程序和web页面之间建立长连接,只需要从一端建立就可以了。
在popup或js或background发起连接请求:

//popup.js或background.js 发起连接需要指定发送到某个标签页
chrome.tabs.query({active: true, currentWindow: true}, tabs => {
	const port = chrome.tabs.connect(tabs[0].id, {name: 'popup'});
	//向指定tabd页发起连接请求
	port.postMessage({cmd: 'popup-connect',value:'extension'});
	port.onMessage.addListener(msg => {
		if(msg.cmd === 'connected') {
			//do something
			port.postMessage({cmd: 'done'});
		}
	});
});

在content-script发起连接和监听消息:

// content-script直接建立长链接
const port = chrome.runtime.connect({name: 'content'});
port.postMessage({cmd: 'cnt-connect'});
port.onMessage.addListener(msg => {
	if(msg.cmd === 'connected'){
		//do something
		port.postMessage({cmd: 'done'});
	}
});

任意一端监听连接请求:

chrome.runtime.onConnect.addListener(port => {
	if(port.name == 'popup') {
		port.onMessage.addListener(msg => {
			if(msg.cmd== 'popup-connect') port.postMessage({cmd: 'connnected'});
		});
	}else if(port.name === 'content'){
		......
	}
});

postMessagemessageChannel 长时效连接通信

  • 同一MessageChannel实例下的port1和port2两个对象可以通过postMessageonmessage方法相互发送和接收消息;
  • port1和port2是MessagePort实例,MessagePort继承了Transferable接口,可在不同可执行上下文之间传递。
  • window.postMessage(message, targetOrigin, [transfer]),第三个参数可以用来传递Transferable对象
//inject-script
const {port1,port2} = new MessageChannel();
window.addEventListener("load", () => {
port1.onmessage = (e) => {
	console.log(e)
}
window.postMessage('来自inject_script的信息', '*', [port2]);
});

//content-script
window.addEventListener('message', e=>{
  e.port[0].postMessage('来自content-script的信息')
});
  • 19
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Chrome扩展是一种用于扩展Chrome浏览器功能的开发工具。严格来说,我们所说的Chrome插件应该叫做Chrome扩展Chrome扩展是在浏览器上运行的程序,可以修改和增强浏览器的功能,例如添加新的工具栏按钮、修改网页内容、处理网络请求等。 如果你对Chrome扩展开发感兴趣,你可以参考Chrome官方开发者文档提供的资源。Chrome开发者文档的主页是https://developer.chrome.com/extensions/devtools,其中提供了详细的开发指南、API文档和示例代码,可以帮助你开始开发Chrome扩展。 在开发Chrome扩展过程中,通信是一个重要的方面。你可能需要与浏览器的不同组件进行通信,包括与当前打开的网页进行交互、与其他扩展或外部应用程序进行通信等。你可以在https://developer.chrome.com/extensions/messaging找到关于Chrome扩展通信的详细信息和示例代码。这些资源可以帮助你了解如何在Chrome扩展中实现不同组件之间的通信。 总结来说,Chrome扩展开发是一种扩展Chrome浏览器功能的方法,你可以通过参考Chrome官方开发者文档获取相关资源和指导。你还可以了解如何在扩展中实现通信。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [【干货】Chrome插件(扩展)开发全攻略](https://blog.csdn.net/qq_34998786/article/details/121782426)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值