【问题标题】:Injecting JS in Google Chrome's page with variables from the userscript?使用用户脚本中的变量在 Google Chrome 页面中注入 JS?
【发布时间】:2010-09-08 21:09:40
【问题描述】:

我有一个在 FireFox 中使用 unsafeWindow 的脚本,因为它不起作用,我已经搜索了另一个选项,并找到了它,我只是想知道:如何将我的用户脚本中的变量用于 unsafeWindow 解决方法?

我的代码是:

// ==UserScript==
// @name   Test
// @description  Test
// @include   http://www.google*
// ==/UserScript==

var toAlert = "This is what I want to alert...";
alert("Before implementation...");
contentEval( function(){ alert(toAlert);});
alert("And after...");
function contentEval(source) {
  // Check for function input.
  if ('function' == typeof source) {
    // Execute this function with no arguments, by adding parentheses.
    // One set around the function, required for valid syntax, and a
    // second empty set calls the surrounded function.
    source = '(' + source + ')();'
  }

  // Create a script node holding this  source code.
  var script = document.createElement('script');
  script.setAttribute("type", "application/javascript");
  script.textContent = source;

  // Insert the script node into the page, so it will run, and immediately
  // remove it to clean up.
  document.body.appendChild(script);
  document.body.removeChild(script);
}

而且它不起作用... 我做错了什么?

【问题讨论】:

  • 您正在附加脚本并立即将其删除,我怀疑这可能是一个原因。
  • 请确认您的函数“contentEval”是否工作正常。

标签: javascript variables google-chrome greasemonkey inject


【解决方案1】:

如果 toAlert 碰巧在页面的全局范围内定义,您的脚本将起作用。

在 Chrome 中,扩展程序/Greasemonkey JavaScript 不能与页面 JavaScript 共享变量或闭包。
这就是为什么您不能直接注入该函数,从扩展范围到页面范围,而必须从源字符串重新创建它。

这意味着如果你在页面范围内创建一个函数,你的函数需要的任何变量或函数必须:

  1. 已在全球范围内出现在源页面中。
    或者
  2. 也可以将脚本写入源页面。

例如,像这样修改你的代码...

//-- Must recreate the variable that the function requires.
scriptStr  = 'var toAlert="' + toAlert +'";';

//-- Now the function.
scriptStr += '(' + source.toString() + ')();'

var script = document.createElement('script');
script.textContent = scriptStr;

...有效,但这种方法显然会变得混乱。

明智的做法是:
(A) 将所有 JavaScript 保留在扩展程序中;不与页面的 JavaScript 交互。

或者 (B) 如果您必须与页面的 JS 交互,或加载像 jQuery 这样的库,则将 所有 代码放在一个 main() 函数中并将其编写到源页面中。

像这样:

function localMain ()
{
    /*--- Put EVERYTHING inside this wrapper, functions and variables.
        Call or use nothing else that's defined in the GM script here.
        Can use objects in the source page's scope, though.
    */
}

//--- Now create the function in the page's scope and run it.
var scriptNode          = document.createElement ("script");
scriptNode.textContent  = localMain.toString() + "\n localMain ();";
document.head.appendChild (scriptNode);

请注意,如果您还将库加载到页面范围内,那么您可能需要使用计时器并检查该库来延迟运行 localMain()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-19
    • 1970-01-01
    • 2012-03-31
    • 2012-05-16
    • 1970-01-01
    • 1970-01-01
    • 2011-06-06
    • 1970-01-01
    相关资源
    最近更新 更多