1

我有一个 Greasemonkey 用户脚本,它通过插入<script>如下标签在非特权上下文中运行其大部分代码:

function code {
  ...
}

var script = document.createElement("script");
script.type = "application/javascript";
script.innerHTML = "(" + code + ")();";
document.body.appendChild(script);

这避免了使用unsafeWindow.

但是,我的代码需要从另一个不支持 JSONP 的域上的 API 获取信息。 GM_xmlhttpRequest可以访问其他域,但仅在特权 Greasemonkey 上下文中可用。

我想编写一个函数,它提供了一个有限的接口并准确地进行了我需要使用的 API 调用GM_xmlhttpRequest,然后将该(理论上安全的)函数公开给正常的页面上下文。我的第一次尝试是这样的:

unsafeWindow.foo = function() {
  console.log("Foo!");
  console.log(GM_xmlhttpRequest.toString());
  GM_xmlhttpRequest({
    method: "GET",
    url: "http://www.example.net/",
    headers: {
      "User-Agent": navigator.userAgent,
      "Accept": "text/html"
    },
    onload: function(response) {
      console.log(response);
      unsafeWindow.console.log(response);
      alert(response);
      unsafeWindow.alert(response);
    }
  });
  console.log("Bar!");
};

有趣的是,当我foo()从页面上下文调用时,我看到“Foo!”、字符串化GM_xmlhttpRequest和“Bar!” 在控制台日志中。但是,我从来没有在控制台或警报中得到响应。如果我GM_xmlhttpRequest在 GM 上下文中自行创建,我会收到警报和日志消息。

问题是:我正在尝试做的事情是否可能?还是有另一种方法来完成同样的事情?

4

1 回答 1

1

啊哈!答案已发布到类似问题

Greasemonkey 是故意这样做的,并在0.7.20080121.0 兼容性页面上提供了一个简单的解决方法:

unsafeWindow.foo = function() {
  window.setTimeout(GM_xmlhttpRequest, 0, {
    // ...
  });
};

这样可行。

于 2009-06-10T19:49:50.467 回答