【问题标题】:Firefox SDK + JQuery AJAX problemsFirefox SDK + JQuery AJAX 问题
【发布时间】:2013-08-13 04:20:02
【问题描述】:

我正在使用 SDK(以前称为 Jetpack)为 Firefox 开发插件。

在我的插件中,我需要通过 JSONP 请求访问远程服务器(由我控制)上的 PHP 脚本的一些数据,然后使用从服务器来更新某些网页元素。

在我的 main.js 文件中,我使用 page-mod 和 contentScriptFile 将 JQuery 库的副本和我自己的 javascript 文件注入到网页中。 我的 javascript 文件使用 JQuery 的“$.ajax”函数来访问远程 PHP 脚本。

问题:从未收到响应。

我偶然发现了这个 StackOverflow 问题,它涉及相同的问题: error in jsonp call ONLY FROM firefox-extension

我已经遵循了那里的一些建议,并通过指定我自己的回调更改了我的 $.ajax 请求,并使用“unsafeWindow.callback”将回调函数添加到我的文件中 - 我不完全理解发生了什么,但似乎 JQuery 获取的“窗口”引用与真正的底层窗口对象不同(我认为这种事情是由 XRayWrapper 隐形处理的,所以对此感到困惑)。

没关系。我得到一个传递给我的回调的参数(我已将参数标记为“数据”),其中包含整个服务器响应 - 我需要的一切。

问题是,当我之前在 .ajax 函数中使用 success: 时,“this”指的是 ajax 对象(我认为 - Javascript 初学者),因此我指的是页面元素想要使用响应数据进行更新。 我无法在自定义回调中访问“this”。

我发现即使我总是从服务器得到响应,并且我的回调触发,JQuery 报告错误 - 如果我指定 error:,那么这将触发。 如果我添加 complete:,它也会触发,但 success: 不会触发。

我认为我可以使用 :complete 代替我的自定义回调,但似乎当调用错误处理代码时,它会清除服务器响应 - 我无法完整访问它:(XHR 对象.responseText 属性在处理完成时为“未定义”:)。

所以,我对所有这一切的拼凑解决方案如下。我有我的自定义回调,它传递了完整的服务器响应。我将它存储在一个全局变量中。 我指定完成:-接下来(或以后)触发-然后从那里访问全局变量,但也可以通过“this”访问我想更新的页面元素。

这让我很担心,因为可能会快速连续发出多个 AJAX 请求,因此我的解决方案取决于响应处理没有“交错” - 换句话说,我正在做一个假设(我不知道是真的)当 JQuery 接收到响应时,它将在开始处理下一个接收到的响应之前触发该响应的所有事件处理程序。 如果不是这样,那么我存储在全局变量中的数据可能与我想成功使用它的页面元素不对应:。到目前为止,它似乎在测试中有效,但可能只是我很幸运。

(旁注:我也使用 QTip2,它是 AJAX 插件 - 也总是抛出错误,而不是无声的。但我发现我可以通过添加错误来抑制它:并设置 xhr.status = 0 -我会在下面发布一个sn-p)。

但这似乎是一种可怕而混乱的做事方式。我不明白为什么 JQuery 在成功接收到服务器响应时会认为出现错误。 而且它的错误处理会破坏这个响应非常不方便,这意味着我无法成功处理它:。

有人有更简洁的解决方案吗?提前谢谢你 - sn-ps 跟随(顺便说一下,这些问题仅在我在我的附加组件中执行所有这些时存在。如果我在独立页面/脚本中执行相同的操作,它执行时不会出错被提升,并且完全符合预期)。

unsafeWindow.callback = function(data)
{
  MyGlobalServerResponseVariable = data;
}

$.ajax(
{
  url: 'http://nottherealurl.com/',
  type: 'GET',
  data: params,
  async: true,
  cache: false,
  contentType: "text/json; charset=utf-8",
  dataType: 'jsonp',
  crossDomain: true,
  jsonpCallback: "callback",

  complete: function(xhr, textStatus)
  {
    var data = MyGlobalServerResponseVariable;
    this.PageElementIWantToUpdate.attr("title", data.somevalue);
    ...
  }
...
}

QTip2 错误抑制:

error: function(xhr, status, error)
{
  xhr.status = 0;
}

最后一点,与上述没有直接关系 - 当我在 Firefox 中执行“文件->打开文件”并选择一个网页时,我的插件没有执行。这是设计的吗?

【问题讨论】:

标签: jquery ajax firefox-addon jsonp firefox-addon-sdk


【解决方案1】:

我建议将数据加载逻辑移至 main.js,使用此上下文中可用的请求 API 来加载数据(请参阅https://addons.mozilla.org/en-US/developers/docs/sdk/latest/modules/sdk/request.html)。

当数据加载完毕后,您可以通过扩展->页面消息(https://addons.mozilla.org/en-US/developers/docs/sdk/latest/dev-guide/guides/content-scripts/using-port.html)将数据发送到页面。

【讨论】:

  • 非常感谢您的回复;我目前正忙于项目的另一个不相关的部分,但当我回来完善这一点时,我肯定会重新考虑你的建议。
【解决方案2】:

当jQuery.ajax 接收时,firefox 将回调从内容代码加载到页面代码(因为window/unsafeWindow 的设计?),所以你不再在你的代码中,而是在站点的js 中。 肯定是在站点的js中找不到回调函数。 因此,您应该将代码中的函数导出到站点代码。 像这样:

function your_fuc(){}
exportFunction(your_fuc, unsafeWindow, {defineAs: "your_fuc"});
//  ....
jQuery.ajax({url:url,data:mdata,jsonp:'callback', jsonpCallback:'window.your_fuc', dataType:"jsonp",crossDomain:true});
但是自从Mozilla说

此外,unsafeWindow 不是受支持的 API,因此可以将其删除或 在 SDK 的未来版本中进行了更改。

使用 jsonp 的最佳方式是将代码注入网站页面 插入

<srcipt src="yoursite.com/your.js">

【讨论】:

  • 感谢陈 x 提供这个答案。自从我从事项目的那一部分以来已经有一段时间了,但我将不得不在某个时候回去更新它,所以我会参考你的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-11
  • 2010-11-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多