使用命名函数作为 jQuery 中 $.getJSON 的回调来满足 Facebook 请求签名需求

Posted

技术标签:

【中文标题】使用命名函数作为 jQuery 中 $.getJSON 的回调来满足 Facebook 请求签名需求【英文标题】:using a named function as the callback for $.getJSON in jQuery to satisfy Facebook request signing demands 【发布时间】:2010-09-17 05:18:17 【问题描述】:

我正在尝试通过 jQuery 访问 Facebook API Admin.getMetrics 方法。我在服务器端正确地编写了请求 url(为了让我的应用程序保密)。然后我将 URL 发送到浏览器以使用 jQuery.getJSON() 进行请求。

Facebook 要求我将我的所有请求参数的副本连同我的应用程序密码一起发送,以验证我的真实性。问题是 jQuery 想要生成回调函数本身的名称,以便与它为您传入的匿名函数提供的名称相匹配,以便在数据返回时调用。因此,函数的名称在jQuery.getJSON() 执行之前不可用,并且由于签名不匹配,Facebook 认为我的请求是不真实的(我发送的签名不包含正确的回调参数,因为直到 jQuery.getJSON() 才生成跑)。

我能想到的解决这个问题的唯一方法是以某种方式将我的函数名称指定为jQuery.getJSON(),而不是让它保持匿名。但我在 jQuery AP 中找不到这样做的任何选项。

【问题讨论】:

【参考方案1】:

唯一对我有用的是以下设置

jQuery.ajax( url: fbookUrl, dataType: "jsonp", type: "GET", cache: true, jsonp: false, jsonpCallback: "MyFunctionName" //insert here your function name );

【讨论】:

【参考方案2】:

jQuery.getScript 的使用结果接近——但不完全——答案。使用 getScript 消除了 jQuery 将动态命名的匿名函数添加到请求参数的需要(尽管如果您继续并像上面的代码一样向它传递匿名函数,它仍然会这样做)。然而,jQuery.getScript 中的默认值,与 jQuery 的 Ajax 库中的所有其他调用一样,是附加一个附加参数 _=12344567(其中 1234567 实际上是一个时间戳)。 jQuery 这样做是为了防止浏览器缓存响应。但是,这个附加功能会破坏我对请求的签名,就像自动命名的回调函数一样。

在 #jquery 的一些帮助下,我了解到让 jQuery 完全不弄乱您的参数的唯一方法是使用带有以下参数的基本 jQuery.Ajax 方法发出请求:

jQuery.ajax(
  url: fbookUrl,
  dataType: "script",
  type: "GET",
  cache: true,
  callback: null,
  data: null
);

(其中fbookUrl 是我尝试使用其完整参数请求的Facebook API url,包括签名和callback=myFunction)。 dataType: "script" 参数指定生成的 JSONP 应填充到页面上的脚本标记中执行,cache: true 告诉 jQuery 允许浏览器缓存响应,即跳过添加时间戳参数。

【讨论】:

添加 $.ajaxSetup(cache:true);调用 getScript 之前的任何位置也会删除 _=12344567 参数。 是的。这种方式可以同时完成这两件事,并且不会影响我可能在同一页面上发出的其他 jQuery Ajax 请求。【参考方案3】:

您可以将 JSONP 选项传递给 $.ajaxSetup,这将允许您修复被调用的函数名称,文档如下:

jsonp 字符串 覆盖 jsonp 请求中的回调函数名称。在“callback=?”中将使用该值代替“callback” GET 的 url 中的查询字符串的一部分或 POST 的数据。所以 jsonp:'onJsonPLoad' 会导致 'onJsonPLoad=?'传递给服务器。

查看这里http://docs.jquery.com/Ajax/jQuery.ajax#options了解更多详情

【讨论】:

这实际上并没有解决问题,因为 jQuery 将声明为位于该问号另一侧的匿名函数生成一个任意名称,因此我的签名请求将失败,因为参数将与我以前签署的不符。 JSONP 在 jQuery 中工作的方式要求它生成一个动态函数,然后代码在窗口上创建一个具有动态名称的函数后将其视为脚本。请参阅下面的帖子。【参考方案4】:

这是带有固定回调的更好解决方案:

window.fixed_callback = function(data)
    alert(data.title);
;

$(function() 
    $.getScript("http://api.flickr.com/services/feeds/photos_public.gne?tags=cats&tagmode=any&format=json&jsoncallback=fixed_callback", function(data) 
    alert('done');  );
);

这个回调的问题是您一次只能处理一种请求,因为该函数是全局注册的。回调函数可能不得不变成它可以检索和调用适当函数的不同类型数据的调度程序。

【讨论】:

以上是关于使用命名函数作为 jQuery 中 $.getJSON 的回调来满足 Facebook 请求签名需求的主要内容,如果未能解决你的问题,请参考以下文章

在 jQuery 中用 Javascript 定义函数

Jquery的命名冲突

使用 Saxon-JS 及其全局 Javascript 函数命名空间在 XSL 中调用 jQuery-UI 组件?

使用对象和自执行匿名函数的 jQuery 命名空间

JQuery 命名空间的最佳实践 + 通用实用程序函数

jQuery名称冲突