javascript - 使用用户脚本中的变量在 Google Chrome 页面中注入(inject) JS?

标签 javascript variables google-chrome greasemonkey inject

我有一个在 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);
}

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

最佳答案

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

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

这意味着,如果您在页面范围内创建函数,则函数所需的任何变量或函数必须:

  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()

关于javascript - 使用用户脚本中的变量在 Google Chrome 页面中注入(inject) JS?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3671930/

相关文章:

Javascript:知道实际的一秒何时被勾选?

CSS Filter 反转规则破坏了 Chrome 68 上的固定位置

python - 如何通过 Python 打开 Chrome 配置文件

javascript - 如何修复 require.ensure 错误 Webpack、Babel6、React?

javascript - "Object doesn' t 支持此操作 "when "newing“嵌套的 Javascript 对象实例

bash - 管道 awk 输出以添加到循环内的变量

java - 在 Java 中,通过 getter 引用字段与通过变量引用字段之间是否存在性能差异?

c - 尝试打印方程的答案并在 C 中得到零。

ajax - 为什么非自定义 header 包含在 Access-Control-Request-Headers 中?

javascript - 为什么我的工厂出现喷油器错误?