如何向Greasemonkey的GM_xmlhttpRequest提供有限的界面到我的页面的Javascript?

时间:2009-06-10 19:30:54

标签: javascript security api greasemonkey

我有一个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上下文中可用。

我想编写一个提供有限接口的函数,并使用GM_xmlhttpRequest完成我需要的API调用,然后将该(理论上安全的)函数暴露给普通页面上下文。我的第一次尝试就是:

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上下文中单独创建GM_xmlhttpRequest,我会收到警报和日志消息。

问题是:我正在尝试做甚么可能吗?或者还有另一种方法可以完成同样的事情吗?

1 个答案:

答案 0 :(得分:1)

啊哈!答案已发布到similar question

Greasemonkey非常有意地这样做,并在0.7.20080121.0 compatibility页面上提供了一个简单的解决方法:

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

有效。