How to transfer data between the content scripts of two different tabs?

gvlasov picture gvlasov · Jul 22, 2012 · Viewed 9.9k times · Source

In my extension I need to transfer some data from one tab's content script to another tab's content script. How can I choose certain tab using chrome.tabs, if I know a part of that tab object's name or url in it? How can two tabs' scripts communicate?

UPDATE:

Apparently I don't have method sendMessage in chrome.extension. When I run the following from content script:

chrome.extension.sendMessage("message");

I get in console:

Uncaught TypeError: Object # has no method 'sendMessage'

Answer

Rob W picture Rob W · Jul 22, 2012

First, note that messages passed within an extension are JSON-serialized. Non-serializable types, such as functions, are not included in the message.

Within a content script, you have to pass the message to the background page, because there is no method to directly access other tabs.

// Example: Send a string. Often, you send an object, which includes
//  additional information, eg {method:'userdefined', data:'thevalue'}
chrome.extension.sendMessage(' ... message ... ');

In the background page, use the chrome.tabs.query method to get the ID of a tab. For the simplicity of the example, I've hardcoded the patterns and urls. It might be a good idea to include the query values from the previous message, in this way: {query:{...}, data:...}.

// background script:
chrome.extension.onMessage.addListener(function(details) {
    chrome.tabs.query({
        title: "title pattern",
        url: "http://domain/*urlpattern*"
    }, function(result) {
        // result is an array of tab.Tabs
        if (result.length === 1) { // There's exactely one tab matching the query.
            var tab = result[0];
            // details.message holds the original message
            chrome.tabs.sendMessage(tab.id, details.message);
        }
    });
});

chrome.tabs.sendMessage was used to pass the original data to a different tab.

Remark: In the example, I only passed the message when the query resulted in one unique tab. When uniqueness is not a prerequisite, just loop through all resulting tabs, using result.forEach or:

for (var i=0, tab; i<result.length; i++) {
    tab = results[i];
    ...
}