我正在尝试编写一个用于发出跨域AJAX请求的用户脚本。
我已经使用@require在我的脚本中包含了jQuery,所有内容似乎都正常工作,直到我尝试运行jQuery.getJSON。
我访问的API支持jsonp,但是我一直收到一条错误,指出jsonp123456789没有定义。
从我能够收集的内容来看,这是因为jQuery将jsonp响应直接写入页面的头部,然后成为沙盒。一旦发生这种情况,jQuery就无法再访问回调,导致它被取消定义。 (我不是100%就这种情况,但似乎对我而言)。
有什么方法可以解决这个问题吗?有人建议我在unsafeWindow中声明回调函数,但我不确定如何做到这一点并且没有设法让它工作。
答案 0 :(得分:16)
如果jQuery在内部使用GM_xmlhttpRequest
,那么你是否可以拥有jQuery方法的所有便利和Greasemonkey的跨站点功能?正如mahemoff指出的那样,Greasemonkey可以让你在不依赖JSONP的情况下提出请求并遇到你所面临的回调问题,但你必须自己处理JSON内容。
我们写了一个可以做到这一点的库:Greasemonkey/jQuery XHR bridge。如果您在用户脚本中@require
使用该脚本,那么所有$.get
和$.getJSON
以及$.post
等jQuery调用都可以跨站点工作,而不依赖于JSONP等技术。
因此,如果您使用此桥接器并只是从URL中删除?callback=?
,那么您的jQuery代码应该无需修改即可运行。 This blog post提供了逐步演练。如果有人对网桥插件有任何问题,意见,错误报告或建议,请告诉我。
答案 1 :(得分:8)
解决方法是使用GM_HttpRequest。对于跨域请求,您可以使用它而不是JSONP,因为与通常的XHR不同,GM_HttpRequest允许跨域调用。你想要这样的东西:
GM_xmlhttpRequest({
method: "GET",
url: "http://example.com/path/to/json",
onload: function(xhr) {
var data = eval("(" + xhr.responseText + ")");
// use data ...
}
});
请注意,此eval的JSON是最简单的方法。如果您想为不受信任的JSON提供更安全的解决方案,则需要包含a small JSON-parsing library。
不幸的是,你还必须wrap a seemingly useless zero-duration setTimeout围绕整个事情。我发现将GM_xmlhttpRequest粘贴在自己的方法中最简单,然后运行setTimeout(makeCall,0);.
您可以看到real example here。
答案 2 :(得分:1)
许多人都知道,谷歌浏览器目前不支持任何便捷的GM_功能。
因此,由于各种沙箱限制(即使使用James Padolsey's Cross Domain Request Script这样的优秀工具),跨站点AJAX请求不可能
我需要一种方法让用户知道我的Greasemonkey脚本何时在Chrome中更新过(因为Chrome也没有这样做...)。我提出了一个解决方案,这里有一个解决方案(并在我的Lighthouse++脚本中使用),值得一读,以便你想要对你的脚本进行版本检查:
http://blog.bandit.co.nz/post/1048347342/version-check-chrome-greasemonkey-script