I have a Greasemonkey userscript which runs most of its code in an unprivileged context by inserting a <script>
tag like so:
function code {
...
}
var script = document.createElement("script");
script.type = "application/javascript";
script.innerHTML = "(" + code + ")();";
document.body.appendChild(script);
This avoids the need to do dangerous things with unsafeWindow
.
However, I my code needs to get information from an API on another domain which doesn't support JSONP. GM_xmlhttpRequest
can access other domains, but is only available in the privileged Greasemonkey context.
I'd like to write a function which provides a limited interface and makes exactly the API call I need using GM_xmlhttpRequest
, and then expose that (theoretically safe) function to the normal page context. My first attempt at that was something like:
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!");
};
Interestingly, when I call foo()
from the page context, I see "Foo!", the stringified GM_xmlhttpRequest
and "Bar!" in the console log. However, I never get the response in the console or in an alert. If I make the GM_xmlhttpRequest
on its own in the GM context, I get both alerts and log messages.
The question is: is what I'm trying to do even possible? Or is there another way to accomplish the same thing?