如何在 Chrome 扩展中的 popup.js 和 background.js 之间进行通信?

IT技术 javascript google-chrome-extension
2021-01-24 12:08:05

来自 popup.js 的消息被两次发布到 background.js,但我从 background.js 中完全没有得到任何信息。

背景.js

function login(username,password){

    console.log(username);
var xhr = new XMLHttpRequest();

xhr.open("POST", "http://localhost:3000/login/", true);
xhr.setRequestHeader('Content-type','application/json; charset=utf-8');
data = {"username":username,"password":password};
console.log(JSON.stringify(data));
xhr.send(JSON.stringify(data));
xhr.onreadystatechange = function() {
  if (xhr.readyState == 4) {
    // JSON.parse does not evaluate the attacker's scripts.
    var resp = JSON.parse(xhr.responseText);
    console.log(resp);
    var lStorage = localStorage;
    localStorage.setItem("username",resp["username"]);
    localStorage.setItem("apiKey",resp["apiKey"]);
    localStorage.setItem("password",resp["password"]);
    console.log(localStorage.getItem("username"));



  }
};


}


chrome.extension.onRequest.addListener(
    function(request, sender, sendResponse){
        console.log("hello");
        if(request.msg == "login") {
            //alert(request.password);
            login(request.username,request.password);}
    }
);

  chrome.extension.onConnect.addListener(function(port) {
  console.log("Connected .....");
  port.onMessage.addListener(function(msg) {
        console.log("message recieved "+ msg);
        port.postMessage("Hi Popup.js");
  });
});

popup.js:

function login(){
alert(document.login.username.value);
chrome.extension.sendRequest({ msg: "login",username:document.login.username.value,password:document.login.password.value});
document.getElementById('openBackgroundWindow').visbility = "hidden";

}

$(document).ready(function (){

checkUserAuth();
console.log("Inside");
$("#openBackgroundWindow").click(login);

});


function checkUserAuth(){
console.log(localStorage.getItem("apiKey"));
if(localStorage.getItem("apiKey") != null)
    {
        $("#openBackgroundWindow").visbility ="hidden";
    }
}


var port = chrome.extension.connect({name: "Sample Communication"});
port.postMessage("Hi BackGround");
port.onMessage.addListener(function(msg) {
        console.log("message recieved"+ msg);
});
3个回答

方法 - A:
使用长期连接,您可以针对任何活动从 background.js 到扩展页面的 popup.jsonly initiated进行通信(这里我包含了 popup.html 和来自 popup.js 的示例通信作为示例)

背景.js

 chrome.extension.onConnect.addListener(function(port) {
      console.log("Connected .....");
      port.onMessage.addListener(function(msg) {
           console.log("message recieved" + msg);
           port.postMessage("Hi Popup.js");
      });
 })

弹出窗口.js

 var port = chrome.extension.connect({
      name: "Sample Communication"
 });
 port.postMessage("Hi BackGround");
 port.onMessage.addListener(function(msg) {
      console.log("message recieved" + msg);
 });

方法 - B :
Direct Manipulation of DOM* 如果你的最终结果是 DOM 的修改,你可以用这个来实现

弹出窗口.html

<html>
    <head>
        <script src="popup.js"></script>
    </head>
    <body>
        <div id="x" value="m">Some thing</div>
    </body>
</html>

背景.js

var views = chrome.extension.getViews({
    type: "popup"
});
for (var i = 0; i < views.length; i++) {
    views[i].document.getElementById('x').innerHTML = "My Custom Value";
}

方法-C:

使用长期连接,您可以从 background.js 到任何活动的扩展页面的 popup.js 进行通信(这里我没有包括 popup.html 和从 background.js 启动的示例通信;

背景.js

chrome.browserAction.onClicked.addListener(function(tab) {

    var port = chrome.extension.connect({
        name: "Sample Communication"
    });
    port.postMessage("Hi BackGround");
    port.onMessage.addListener(function(msg) {
        console.log("message recieved" + msg);
    });

});

我已经更改了您的代码,并在消除了一些内容并使其成为一个简单版本后使其运行。在此骨架上添加 AJAX 请求和 HTML DOM 的代码(确保<script>在 head 部分添加标签并chrome.extension.onConnect.addListener删除(xhr.readyState == 4)代码;)

弹出窗口.html

<html >
    <head>
        <script src="popup.js"></script>
    </head>
    <body></body>
</html>

清单文件.json

{
    "name": "Demo",
    "version": "1.0",
    "manifest_version": 2,
    "description": "This is a demo",
    "browser_action": {
        "default_popup": "popup.html"
    },
    "background": {
        "scripts": ["background.js"]
    },
    "permissions": ["<all_urls>",
        "storage",
        "tabs"
    ]
}

背景.js

chrome.extension.onConnect.addListener(function(port) {
    console.log("Connected .....");
    port.onMessage.addListener(function(msg) {
        console.log("message recieved " + msg);
        port.postMessage("Hi Popup.js");
    });
});

弹出窗口.js

var port = chrome.extension.connect({
    name: "Sample Communication"
});
port.postMessage("Hi BackGround");
port.onMessage.addListener(function(msg) {
    console.log("message recieved" + msg);
});
我可以通过 popup.js 与后台页面进行通信,但反过来不行。
2021-03-18 12:08:05
我什至没有检查 popup.js。可怕!原谅我的愚蠢。
2021-03-31 12:08:05
是的。我这样做了,但控制台上仍然没有说 Hi Popup.js
2021-04-06 12:08:05
@Puck:代码 port.postMessage("Hi Popup.js"); 在 background.js 中正在做从 background.js 到 popup.js 的通信
2021-04-11 12:08:05
@Puck:它在这里工作得很好:如果你正在使用,chrome.browserAction.onClicked.addListener(你不能在这里有 popup.html,尝试使用带有有效 manifest.json 的代码;它会起作用,如果没有用您用于测试的所有内容更新您的问题,将从那里选择它
2021-04-12 12:08:05

这可以用于 2 路通信。两个文件中都有相同的代码。

popup.js 和 background.js

//for sending a message
chrome.runtime.sendMessage({greeting: "hello"}, function(response) {

});

//for listening any message which comes from runtime
chrome.runtime.onMessage.addListener(messageReceived);

function messageReceived(msg) {
   // Do your work here
}

参考:https : //developer.chrome.com/extensions/runtime#method-sendMessage

全双工通讯

background.js异步调用方法popup.js返回响应

Popup.js:

// wrapper method 
function getContent() {
    callEventPageMethod('getContent', 'some parameter', function (response) {
        doSomethingWith(response);
    });

}

//generic method
function callEventPageMethod(method, data, callback) {
    chrome.runtime.sendMessage({ method: method, data: data }, function (response) {
        if(typeof callback === "function") callback(response);
    });
}

背景.js/eventPage.js:

chrome.runtime.onMessage.addListener(callback);
function callback(obj, sender, sendResponse) {
    if (obj) {
        if (obj.method == 'getContent') {
            getContent(sendResponse);
        } else if (obj.method == 'othermethod') {

        }
    }
    return true; // remove this line to make the call sync!
}


//some async method
function getContent(sendResponse) {
    chrome.storage.local.get(["mydata"], function (obj) {
        var mydata = $.trim(obj["mydata"]);
        sendResponse(mydata);
    });
}

如果需要background.js调用popup.js方法,则在文件中交换上述代码。


方法二: 可以将后台页面的引用加载到一个变量中,访问所有方法。

var bgPage = chrome.extension.getBackgroundPage();
 var response =  bgPage.someMethodInBGPage();