2014-02-12 194 views
8

我想開發只能在指定頁面上工作的擴展 - 如果頁面所有者在其代碼中添加全局變量(例如ACCEPT_STATS = true;)我想執行指定的代碼。Chrome擴展 - 從擴展訪問文檔/頁面變量

我已經綁定我的函數onload事件,我還發現,解決方案是如何做到這一點在Firefox:

var win = window.top.getBrowser().selectedBrowser.contentWindow; 
if (typeof win.wrappedJSObject.ACCEPT_STATS !== 'undefined') { 
    // code to run if global variable present 
} 

,但我不能讓Chrome在這項工作。有沒有可能訪問文檔的全局變量拋出Chrome擴展代碼?

我的擴展的代碼被注入爲內容腳本。

+0

這聽起來象是一個內容腳本應該做的,不是嗎? https://developer.chrome.com/extensions/content_scripts.html –

+0

「但是,內容腳本有一些限制,它們不能:[...] 使用由網頁或其他內容腳本定義的變量或函數」 – kmoe

+0

內容腳本在_isolated world_中執行。你將不得不將代碼注入頁面。 –

回答

1

運行在頁面上的JavaScript運行在與您使用內容腳本注入的JavaScript不同的「孤立的世界」中。由於安全原因,Chrome瀏覽器會將這兩個世界分開,因此您無法在任何窗口中閱讀window.XYZ。更多關於獨立世界如何工作的信息:http://www.youtube.com/watch?v=laLudeUmXHM

實現此功能的正確方法是通過window.postMessage API與頁面進行通信。我這裏還有我怎麼會去一下:

  1. 注入內容腳本到各選項卡
  2. 通過window.postMessage
  3. 將消息發送給標籤
  4. 如果頁面瞭解到此消息,它正確響應(再次通過window.postMessage)
  5. 內容腳本執行它需要執行的代碼。

HTH

13

是,包括腳本到頁面並運行從網頁運行腳本一個孤立的環境。

但是,可以通過將內聯腳本通過附加到文檔的html腳本標籤推入運行時上下文來解決孤立的世界問題。該內聯腳本然後可以拋出一個自定義事件。

孤立的上下文中包含的腳本可以監聽該事件並相應地作出響應。

因此,在你包含腳本代碼會是這個樣子:

// inject code into "the other side" to talk back to this side; 
var scr = document.createElement('script'); 
//appending text to a function to convert it's src to string only works in Chrome 
scr.textContent = '(' + function() { 
    var check = [do your custom code here]; 
    var event = document.createEvent("CustomEvent"); 
    event.initCustomEvent("MyCustomEvent", true, true, {"passback":check}); 
    window.dispatchEvent(event); } + ')();' 
//cram that sucker in 
(document.head || document.documentElement).appendChild(scr); 
//and then hide the evidence as much as possible. 
scr.parentNode.removeChild(scr); 
//now listen for the message 
window.addEventListener("MyCustomEvent", function (e) { 
    var check = e.detail.passback; 
    // [do what you need to here]. 
}); 
+1

這是一個很好的解決方案,在我看來。但請注意,不推薦使用「initCustomEvent」。相反,您可以使用「CustomEvent」構造函數。來源:https://developer.mozilla。org/en-US/docs/Web/API/CustomEvent/initCustomEvent – Luoruize

+0

我得到一個'Uncaught TypeError:「)();」不是函數錯誤。這個解決方案是否仍然有效? –

+1

它實際上是通過傳遞一個多行字符串來工作的:'scr.textContent ='' var event = document.createEvent(「CustomEvent」); event.initCustomEvent(「MyCustomEvent」,true,true,{「passback」:token}); window.dispatchEvent(event); \';' –