有一个为google-chrome编写的插件,可以将来自网站的消息连接到用户的计算机。强制要求是通过background.js脚本的插件保持一个持续的连接,实际上,它通过端口保持连接,但是我不能以任何方式将从主机接收到的响应发送到站点。
也就是说,我从站点向插件发送一条消息,如下所示:
//站点上的脚本
chrome.runtime.sendMessage(extensionId, {type: "SEND_FROM_WEB_SITE"}, function(response){
console.log(response)
})在这里,我通过端口建立到用户计算机的永久连接,从网站接收消息,并尝试将响应发送回站点。
//脚本background.js
// establishing a connection
connect()
function onNativeMessage(message){
if(message.type == 'GET_FROM_HOST') {
// HERE I RECEIVE AN ANSWER FROM THE USER'S COMPUTER WHICH SHOULD BE TRANSFERRED TO THE SITE? QUESTION HOW
console.log(message);
}
}
function connect(){
port = chrome.runtime.connectNative(hostName);
port.onMessage.addListener(onNativeMessage);
}
function sendNativeMessage(message) {
port.postMessage(message);
}
// listening to the message from the website
chrome.runtime.onMessageExternal.addListener(function(request, sender, sendResponse) {
if (request.type == "GET_FROM_WEB_SITE"){
// WE RECEIVE A MESSAGE FROM THE WEE SITE AND SEND IT TO THE USER'S COMPUTER, HOW DO I TRANSFER THROUGH "sendResponse" THE RESPONSE TO THE SITE
sendNativeMessage(request);
}
});以防万一,具有权限// manifest.json的清单文件
{
"name": "app plugin",
"short_name": "app",
"description": "app",
"manifest_version": 2,
"permissions": ["nativeMessaging", "activeTab", "tabs", "storage"],
"background": {
"scripts": ["background.js"],
"persistent": false
},
}发布于 2020-09-15 14:04:13
您所需要做的就是记住sendResponse,直到收到本机主机的响应,并使用return true保持onMessageExternal通道打开:
let savedSendResponse;
let port = chrome.runtime.connectNative(hostName);
port.onMessage.addListener(message => {
if (savedSendResponse) {
savedSendResponse(message);
savedSendResponse = null;
}
});
chrome.runtime.onMessageExternal.addListener((request, sender, sendResponse) => {
port.postMessage(request);
savedSendResponse = sendResponse;
return true; // keep the channel open until savedSendResponse is called
});然而,如果a)您的主机应用程序异步处理消息,以及b)可能打开同一站点的多个选项卡,并且每个选项卡都可以发送一条消息,那么就会出现复杂的情况。在这种情况下,我们需要分别记住每个sendResponse。我们可以通过为主机和分机之间的消息分配一个临时的内部id来实现。主机应用程序应该从消息中读取此id,并在其响应中写入相同的id。
let sendMap = new Map();
let port = chrome.runtime.connectNative(hostName);
port.onMessage.addListener(message => {
const send = sendMap.get(message.id);
if (send) {
sendMap.delete(message.id);
send(message);
}
});
chrome.runtime.onMessageExternal.addListener((request, sender, sendResponse) => {
request.id = performance.now();
sendMap.set(request.id, sendResponse);
port.postMessage(request);
return true; // keep the channel open until sendResponse is called
});https://stackoverflow.com/questions/63895743
复制相似问题