Chrome扩展程序:将消息传递到内容脚本

时间:2014-05-09 00:08:37

标签: javascript html json google-chrome-extension

这个问题在2014年5月12日星期一进行了大量编辑

我已经想出了如何使用非常基本的设置向内容脚本发送消息,但是当我尝试添加一些事情如事件监听器或窗口时,事情就会停止工作......

manifest.json文件在所有不同版本的代码中保持不变:

{
    "manifest_version" : 2,
    "name" : "Message Test",
    "version" : "1.0",

    "browser_action": { 
        "default_popup": "popup.html"
    },

    "content_scripts": [
        {
        "matches" : ["<all_urls>"],
        "js": ["content-script.js"]
        }
    ]    
}

popup.html文件在所有不同版本中保持相同:

<html>
  <head>
    <script src="message.js"></script>
  </head>
<body>
  <button type="button" id="Popup Window">Popup Window</button>
</body>
</html>

content-script.js文件保持相对相同:

var Mymessage;

chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
    if (message.greeting == "Can you hear me?"){
        Mymessage = message.theMessage;
    }
    else{
        sendResponse({});
    }
    alert(Mymessage);
});

这是最后一个存在问题的文件...... message.js:

window.addEventListener('load', function () {
    var myWindow;
    function startFunction() {
        myWindow = window.open("https://www.google.com/", "myWindow", "width=500,height=500");

        function MyMessage (){
          chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
            var tab = tabs[0];
            chrome.tabs.sendMessage(tab.id, {
              greeting: "Can you hear me?",
              theMessage: "Chrome Extension Message"
            }, function(response){});
          }
        window.setTimeout(MyMessage , 3000);
    }
    var Process = document.getElementById('Popup Window');
    Process.addEventListener('click', startFunction);
});

如果我删除功能 MyMessage window.setTimeout(MyMessage,3000); ,则弹出按钮会成功打开一个新窗口。如果我删除除MyMessage函数中的代码之外的其余文件,每当我在随机页面上并单击其扩展图标时,content-script.js文件中的警报将会消失。我正在尝试更改它,以便在用户单击popup.html中的按钮并且仅在弹出窗口创建新窗口之后才会发送消息。

2 个答案:

答案 0 :(得分:0)

您正在针对按钮注册2个单击事件侦听器,一个在message.js文件中,另一个在window.js中注册

其次,你没有在清单文件中使用权限,

 "permissions": [
    "tabs"
  ],

在文件中创建单个事件侦听器,并将消息从其发送到内容脚本。希望以下代码可以帮助您...

<强> popup.js

    chrome.tabs.getCurrent(
            function(tab){
                console.log(tab);
                chrome.tabs.sendMessage(tab.id, "doSomething");     
            }
        ); 

如果您要向正在浏览的标签发送消息,请使用以下代码的tab.id,它会提供正确的标签ID

chrome.tabs.query({"status":"complete","windowId":chrome.windows.WINDOW_ID_CURRENT,"active":true}, function(tabs){
         console.log(JSON.stringify(tabs[0]));
         console.log(tabs[0].id); 
    });

<强> contentscript.js:

var Message;

    chrome.runtime.onMessage.addListener(
      function(request, sender, sendResponse) {
        if (request.greeting == "Can you hear me?"){
          Message = theMessagePassed;
          sendResponse({farewell: "goodbye"});
          alert(Message);
        }
      }
    );

答案 1 :(得分:0)

如果其他答案没有帮助:您可以使用后台脚本作为中间步骤。

从内容脚本发送消息(不指定任何发件人),然后在后台脚本的单个onMessage侦听器中使用大的switch-case或if-else-if树抓取该消息,从那里播放并抓住该消息广播*在...首先要在哪里发送消息。

编辑:

*我可能对Opera或Firefox感到困惑,但其中一个浏览器不仅具有该功能,而且限制只能通过后台脚本广播,而不是精确定位收件人。但显然,there is a way可以创建自己的广播方法。

回答你的问题:

您可以使用任意数量的属性(使用静态值或变量)创建一个匿名对象,如以下示例所示。

虽然那些只能作为字符串发送(或者它们存储为字符串?不记得了),你仍然可以将布尔值,数字和数组(可能还有JSON)转换成字符串,然后在接收端重新转换它们

contentScript.js

 // instantiation
var
  name = 'george',
  age = 21,
  friends = [ 'tim', 'steve' ];

 // convert
age = String(age);
friends = friends.join();

 // messaging
chrome.runtime.sendMessage({
  method: 'setPerson',
  type: 'person',
  name: name,
  age: age,
  friends: friends
}, function(response){

  if (response) {
    console.log( 'response value: '+ response.value );
  }
  else {
    console.log( 'it did not work.' );
  }
});

background.js

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {

  var
    response = null,
    temp = null,
    s = '';

  if (  request  &&  (request.method === 'setPerson')  ) {

    s += 'name: '+ request.name +'\n';
    s += 'type: '+ request.type +'\n';

    temp = isNaN( request.age ) ? request.age : parseInt( request.age, 10 );
    s += 'age: '+ temp +' — '+ typeof temp +'\n';

    temp = (request.friends === null) ? [null] : request.friends.split(',');
    s += 'friends: '+ temp +' — '+ temp.length +'\n';

    alert(s);

    response = 'it worked.';
  }

  sendResponse({value: response});
});

(您需要有一个background.html页面才能查看这些后台控制台日志。)

EDIT²:忘记后台控制台。我们只使用警报,ffs。