我有一个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
,我会收到警报和日志消息。
问题是:我正在尝试做甚么可能吗?或者还有另一种方法可以完成同样的事情吗?
答案 0 :(得分:1)
啊哈!答案已发布到similar question。
Greasemonkey非常有意地这样做,并在0.7.20080121.0 compatibility页面上提供了一个简单的解决方法:
unsafeWindow.foo = function() {
window.setTimeout(GM_xmlhttpRequest, 0, {
// ...
});
};
有效。