jQuery.getJSON在Greasemonkey用户脚本中的使用

11

我正在尝试编写一个用户脚本,用于进行跨域AJAX请求。

我已经使用 @require 引入了jQuery,并且一切都似乎工作得很好,直到我尝试运行 jQuery.getJSON。

我要访问的API支持jsonp,但是我一直收到一个错误,指出jsonp123456789未定义。

据我所知,这是由于jQuery将jsonp响应直接写入页面头部,从而变为沙盒状态。一旦发生这种情况,jQuery就无法再访问回调函数,导致该函数未定义。(我不确定是否完全如此,但我认为这很可能是原因)。

有没有什么办法可以解决这个问题?有人建议我在 unsafeWindow 中声明回调函数,但我不确定如何做到这一点,也没有成功。

3个回答

16
如果jQuery内部使用GM_xmlhttpRequest,那么您就可以拥有所有jQuery方法的便利性和Greasemonkey的跨站功能,这不是很好吗?正如mahemoff所指出的那样,Greasemonkey可以让您在不依赖JSONP并遇到您正在面对的回调问题的情况下进行请求,但是您必须自己处理JSON内容。
我们编写了一个库来解决这个问题:Greasemonkey/jQuery XHR bridge。如果您在用户脚本中@require该脚本,那么所有$.get$.getJSON$.post等jQuery调用都将在不依赖于JSONP等技术的情况下实现跨站功能。
因此,如果您使用此桥接器并简单地从URL中删除?callback=?,则您的jQuery代码应该可以无需修改即可工作。这篇博客文章提供了一步步的操作说明。如果有任何关于桥接器插件的问题、评论、错误报告或建议,请告诉我。

1
嗨,Nick,有趣的是,当我第一次尝试解决这个问题时,我遇到了你的脚本,但没有意识到需要删除回调才能使事情正常工作,所以放弃了。感谢您回答这个问题并解释需要做什么。 - user199348
谢谢你,这让我的任务变得更容易了! - GrayB

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,则需要包含一个小的JSON解析库。
不幸的是,您还需要在整个过程中包装一个看似无用的零持续时间setTimeout。我发现将GM_xmlhttpRequest放入自己的方法中,然后运行setTimeout(makeCall, 0); 最容易。
您可以在此处查看真实示例

1
许多人都知道,Google Chrome目前不支持任何方便的GM_函数。因此,由于各种沙盒限制(即使使用像James Padolsey的跨域请求脚本这样的工具),无法进行跨站点AJAX请求。
我需要一种方式让用户知道我的Greasemonkey脚本在Chrome中已更新(因为Chrome也没有这个功能...)。我想出了一个解决方案,这里有文档记录(并在我的Lighthouse ++脚本中使用),对于那些想要版本检查其脚本的人来说,值得一读。

http://blog.bandit.co.nz/post/1048347342/version-check-chrome-greasemonkey-script


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接