我正在使用 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无形地处理的,所以对此感到困惑)。
没关系。我得到一个传递给我的回调的参数(我标记了参数“data”),其中包含整个服务器响应 - 我需要的一切。
问题是,当我以前在.ajax函数中使用 success:时,“this”指的是ajax对象(我认为 - Javascript初学者),然后是页面元素我想要用响应数据更新。 我在自定义回调中无法访问“this”。
我发现即使我总是从服务器得到响应,并且我的回调触发,JQuery报告错误 - 如果我指定错误:,那么这将触发。 如果我添加完成:,则会触发,但成功:永远不会触发。
我认为我可以使用:完成代替我的自定义回调,但看起来当调用错误处理代码时,它会清除服务器响应 - 我无法完全访问它:( XHR对象处理完成时,.responseText属性为“未定义”:)。
所以,我对所有这些的拼凑解决方案如下。我有我的自定义回调,它传递了完整的服务器响应。我将它存储在一个全局变量中。 我指定完成: - 接下来(或稍后)触发 - 然后从那里访问全局变量,但是也可以通过“this”访问我想要更新的页面元素。
这让我很担心,因为几个AJAX请求可以快速连续进行,所以我的解决方案取决于没有响应处理的“交错” - 换句话说,我正在做一个假设(我不知道是的,当JQuery收到响应时,它会在开始处理下一个收到的响应之前触发该响应的所有事件处理程序。 如果不是这样,那么我存储在我的全局变量中的数据可能与我想要成功使用它的页面元素不对应:它似乎在测试中起作用,但它可能就是我很幸运。
(旁注:我也使用QTip2,它是AJAX插件 - 总是会抛出一个错误,而不是一个沉默。但我发现我可以通过添加错误来抑制它:并设置xhr.status = 0 - 我将在下面发布一个片段。
但这似乎是一种可怕的混乱方式。我不明白为什么JQuery认为在成功收到服务器响应时出现错误。 它的错误处理破坏了这种反应非常不方便,这意味着我无法取得成功:。
有没有人有更整洁的解决方案?提前谢谢 - 要遵循的片段(顺便说一下,当我在我的插件中执行所有这些操作时,这些问题才会存在。如果我在独立的页面/脚本中执行相同的操作,它会在没有错误的情况下执行,正如预期的那样。)
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中执行“文件 - >打开文件”并选择一个网页时,我的附加组件不会被执行。这是设计吗?
答案 0 :(得分:1)
我建议将数据加载逻辑移到main.js,使用此上下文中可用的Request 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)。
答案 1 :(得分:1)
当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});

此外,unsafeWindow不是受支持的API,因此可以将其删除或 在SDK的未来版本中已更改。
使用jsonp的最佳方法是将代码注入网站的页面 插入
<srcipt src="yoursite.com/your.js">
&#13;