2013-03-30 20 views
13

Sto scrivendo un plug-in di Chrome con uno script di contenuto e uno script di sfondo, e sto cercando di far comunicare i due.chrome.runtime.sendMessage non funziona come previsto

Nel mio script contenuti, sto facendo

chrome.runtime.sendMessage({greeting: "hello"}, function(response) { 
     console.log(response.farewell); 
}); 

e nel mio script fondo, sto facendo

chrome.runtime.onMessage.addListener(
    function(request, sender, sendResponse) { 
     console.log(sender.tab ? 
      "from a content script:" + sender.tab.url : 
      "from the extension"); 
     if (request.greeting == "hello") 
      sendResponse({farewell: "goodbye"}); 
    } 
); 

miei sguardi si manifestano in questo modo:

{ 
    "manifest_version": 2, 
    "name": "Tesing Phase", 
    "version": "1.0", 
    "background": { 
     "persistent": false, 
     "scripts": ["bgscript.js"] 
    }, 
    "content_scripts": [{ 
     "js": ["contentscript.js"], 
     "all_frames": true, 
     "run_at" : "document_start", 
     "matches": ["*://*/*"] 
    }], 
    "web_accessible_resources": ["script.js"] 
} 

Quando ho esegui il mio plugin, ricevo il seguente errore:

Uncaught TypeError: Object #<Object> has no method 'sendMessage' 

Ho provato a registrare chrome.runtime e non c'era alcun metodo sendMessage. Sto usando la versione 25.0 di Chromium su Ubuntu. Ho provato a usare anche sendRequest, ma ha detto che è deprezzato e dovrebbe essere usato sendMessage.

Qualcuno può indicarmi cosa mi manca qui? Ci sono permessi necessari per far funzionare questo?

risposta

34

chrome.runtime.sendMessage/onMessage (e di altri relativi eventi/metodi come connect) sono stati introdotti in Chrome 26.

Se si vuole scrivere un prolungamento che è compatibile con Chrome 20 - 25, utilizzare chrome.extension.sendMessage.

Un modo per ottenere una compatibilità ottimale è definire autonomamente i metodi chrome.runtime. Ad esempio, eseguire il seguente codice prima del resto del codice (sfondo/script contenuto):

if (!chrome.runtime) { 
    // Chrome 20-21 
    chrome.runtime = chrome.extension; 
} else if(!chrome.runtime.onMessage) { 
    // Chrome 22-25 
    chrome.runtime.onMessage = chrome.extension.onMessage; 
    chrome.runtime.sendMessage = chrome.extension.sendMessage; 
    chrome.runtime.onConnect = chrome.extension.onConnect; 
    chrome.runtime.connect = chrome.extension.connect; 
} 

allora si può solo utilizzare l'ultima formato API:

// Bind event: 
chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) { 
    // Do something 
}); 

// Send message: 
chrome.runtime.sendMessage({greeting: 'hello'}); 

Se si sente a disagio con la modifica metodi per l'oggetto chrome.runtime, è possibile utilizzare il seguente approccio invece:

var runtimeOrExtension = chrome.runtime && chrome.runtime.sendMessage ? 
         'runtime' : 'extension'; 

// Bind event: 
chrome[runtimeOrExtension].onMessage.addListener(
    function(message, sender, sendResponse) { 
    // Do something 
}); 

// Send message: 
chrome[runtimeOrExtension].sendMessage({greeting: 'hello'}); 
+2

Grazie lot.It lavorato utilizzando chrome.extension.I sottile k questa informazione manca nelle pagine di google chrome dev. –

+0

sembra fantastico, ma questa metodologia è ancora valida per le versioni di Chrome fino a 31? o dovrebbe essere adattato? e qualcuno sa se i vecchi metodi di passaggio dei messaggi deprecati sono stati eliminati completamente dall'ultima versione di chrome – user280109

+0

@ user280109 È ancora valido. Anche se potresti semplicemente usare 'chrome.runtime' senza livelli di compatibilità, perché quasi nessuno usa Chrome 25- più grazie all'aggiornamento automatico di Google. –

Problemi correlati