2012-11-21 62 views
6

我在test.js下面的代碼,其前右< /體運行>:訪問變量從Greasemonkey的頁&反之亦然

alert('stovetop'); 
alert(greasy); 

我在test.user下面的代碼.js文件

(function() { 

    'use strict'; 
    var greasy = 'greasy variable'; 
    document.title = 'greasy title'; 

}()); 

「爐子」被驚動了,所以我知道JavaScript的工作頁面,document.title得到改變,所以我知道該腳本JavaScript的工作。然而,在網頁上我得到的錯誤:

Error: ReferenceError: greasy is not defined Source File: /test.js

如何從網頁訪問由Greasemonkey設置的變量,反之亦然?

+1

如果你這樣做,它將只能在Firefox作爲Chrome沙箱用戶腳本。 – apscience

回答

25
  • Greasemonkey腳本在一個單獨的操作範圍,並且還可以操作在沙箱中,這取決於@grant settings

  • 此外,該問題代碼將功能範圍內的greasy隔離(如gladoscc所述)。

  • 最後,在默認情況下,test.js將觸發的Greasemonkey腳本執行之前,所以不會看到任何一組變量,反正。使用@run-at document-start來解決這個問題。


因此,鑑於這種test.js</body>前右運行:

window.targetPages_GlobalVar = 'stovetop'; 

console.log ("On target page, local global: ", targetPages_GlobalVar); 
console.log ("On target page, script global: ", gmScripts_GlobalVar); 

然後下面的工作:

沒有沙箱:

// ==UserScript== 
// @name  _Greasemonkey and target page, variable interaction 
// @include  http://YOUR_SERVER.COM/YOUR_PATH/* 
// @include  http://jsbin.com/esikut/* 
// @run-at  document-start 
// @grant  none 
// ==/UserScript== 

//--- For @grant none, could also use window. instead of unsafeWindow. 
unsafeWindow.gmScripts_GlobalVar = 'greasy'; 

console.log ("In GM script, local global: ", unsafeWindow.targetPages_GlobalVar); 
console.log ("In GM script, script global: ", gmScripts_GlobalVar); 

window.addEventListener ("DOMContentLoaded", function() { 
    console.log ("In GM script, local global, after ready: ", unsafeWindow.targetPages_GlobalVar); 
}, false); 


隨着沙箱,無功能範圍,unsafeWindow
== > 重要更新:Greasemonkey changed unsafeWindow handling with version 2.0, the next sample script will not work with GM 2.0 or later。另外兩個解決方案仍然有效。

// ==UserScript== 
// @name  _Greasemonkey and target page, variable interaction 
// @include  http://YOUR_SERVER.COM/YOUR_PATH/* 
// @include  http://jsbin.com/esikut/* 
// @run-at  document-start 
// @grant GM_addStyle 
// ==/UserScript== 
/*- The @grant directive is needed to work around a design change 
    introduced in GM 1.0. It restores the sandbox. 
*/ 

unsafeWindow.gmScripts_GlobalVar = 'greasy'; 

console.log ("In GM script, local global: ", unsafeWindow.targetPages_GlobalVar); 
console.log ("In GM script, script global: ", unsafeWindow.gmScripts_GlobalVar); 

window.addEventListener ("DOMContentLoaded", function() { 
    console.log ("In GM script, local global, after ready: ", unsafeWindow.targetPages_GlobalVar); 
}, false); 


隨着沙箱,無功能範圍,腳本注入

// ==UserScript== 
// @name  _Greasemonkey and target page, variable interaction 
// @include  http://YOUR_SERVER.COM/YOUR_PATH/* 
// @include  http://jsbin.com/esikut/* 
// @run-at  document-start 
// @grant  GM_addStyle 
// ==/UserScript== 
/*- The @grant directive is needed to work around a design change 
    introduced in GM 1.0. It restores the sandbox. 
*/ 

function GM_main() { 
    window.gmScripts_GlobalVar = 'greasy'; 

    console.log ("In GM script, local global: ", window.targetPages_GlobalVar); 
    console.log ("In GM script, script global: ", window.gmScripts_GlobalVar); 

    window.addEventListener ("DOMContentLoaded", function() { 
     console.log ("In GM script, local global, after ready: ", window.targetPages_GlobalVar); 
    }, false); 
} 

addJS_Node (null, null, GM_main); 

function addJS_Node (text, s_URL, funcToRun, runOnLoad) { 
    var D         = document; 
    var scriptNode       = D.createElement ('script'); 
    if (runOnLoad) { 
     scriptNode.addEventListener ("load", runOnLoad, false); 
    } 
    scriptNode.type       = "text/javascript"; 
    if (text)  scriptNode.textContent = text; 
    if (s_URL)  scriptNode.src   = s_URL; 
    if (funcToRun) scriptNode.textContent = '(' + funcToRun.toString() + ')()'; 

    var targ = D.getElementsByTagName ('head')[0] || D.body || D.documentElement; 
    targ.appendChild (scriptNode); 
} 

注:

  1. 您可以針對測試這些腳本3210。
  2. 沒有沙箱,unsafeWindowwindow是一樣的。
  3. 這些腳本的製作控制檯上的相同的輸出:

    In GM script, local global: undefined 
    In GM script, script global: greasy 
    On target page, local global: stovetop 
    On target page, script global: greasy 
    In GM script, local global, after ready: stovetop 
    
  4. 腳本注入代碼將在各種除了Firefox瀏覽器的工作。 unsafeWindow目前僅適用於Firefox + Greasemonkey(或Scriptish)或Chrome + Tampermonkey。

+0

真棒,謝謝你的偉大的解釋! –

+0

btw http://wiki.greasespot.net/UnsafeWindow說不安全使用unsafeWindow,在這種情況下更安全的替代方法是什麼? –

+1

「更安全」的選擇是使用'@grant none'方法,但用'window'替換'unsafeWindow'(儘管'@grant none'生效時它們是相同的),要使用**或** *腳本注入*方法。 ...但是,使用'unsafeWindow'的風險大大增加 - 沒有真正的漏洞報告。只要您不在一個主動針對通用汽車腳本的網站上,就沒有風險。 –

1

您的變量greasy在匿名函數的範圍內定義。即使在你的腳本中,你也不能訪問greasy,除非它是你函數的一部分。例如:

(function(){ 
    var foo = 5; 
    alert(foo); 
}(); 
alert(foo); //ERROR, because foo is undefined outside of the function. 

這樣來做:

var foo = 5; 
(function(){ 
    alert(foo); 
}(); 
alert(foo); 

而且,你爲什麼把在一個匿名函數所有的代碼,然後執行它?

+0

我剛使用了一個greasemonkey模板腳本,它在匿名函數中有示例代碼。我認爲它是greasemonkey腳本所必需的。我將var聲明移到了函數的外部,我仍然無法通過頁面上的test.js腳本警告變量值。 –

+0

難道是我的test.js腳本在Greasemonkey之前運行嗎?如果是這樣,我該如何推遲呢? –

相關問題