我正在使用SDK(以前称为Jetpack)为开发一个附加组件。
在我的附加程序中,我需要通过JSONP请求访问一些数据到远程服务器上的一个PHP脚本(由我控制),然后使用从服务器返回的数据来更新某些网页元素。
在我的main.js文件中,我使用page-mod和contentScriptFile将JQuery库的副本注入到web页面中,并使用自己的javascript文件。我的javascript文件使用JQuery的"$.ajax“函数访问远程PHP脚本。
问题是:从来没有收到过答复。
我偶然发现了一个StackOverflow问题,它处理的是同一个问题:error in jsonp call ONLY FROM firefox-extension
我遵循了其中的一些建议,并通过指定自己的回调来更改我的$.ajax请求,并使用"unsafeWindow.callback“将回调函数添加到我的文件中--我不完全理解发生了什么,但是JQuery获得的”窗口“引用似乎与真正的底层窗口对象不一样(我认为这类事情应该由XRayWrapper来处理,对此非常困惑)。
没关系。我得到一个传递给回调的参数(我给参数“data”贴上了标签),它包含整个服务器响应--我需要的所有东西。
问题是,当我以前在函数中使用时,"this“指的是ajax对象(我想是- Javascript初学者),然后是我想用响应数据更新的页面元素。在我的自定义回调中,我失去了“此”的访问权限。
我所发现的是,即使我总是从服务器获得响应,并触发回调,JQuery还是会报告一个错误--如果我指定了 error :,那么它就会触发。如果我添加了一个complete:,这也会触发,但是成功:永远不会触发。
我以为我可以使用:complete来代替我的自定义回调,但是当调用错误处理代码时,它会清除服务器响应--我无法完整地访问它:(当处理完成时,XHR对象.responseText属性是“未定义的”)。
因此,我拼凑出的解决方案如下。我有我的自定义回调,它被传递给整个服务器响应。我把它存储在一个全局变量中。我指定了complete:-这将触发next (或更高版本)-然后从那里访问全局变量,但也可以通过"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中做"File->Open File“并选择一个网页时,我的外接程序不会执行。这是故意的吗?
发布于 2013-09-25 07:24:01
我建议将数据加载逻辑移到main.js,使用此上下文中可用的Request加载数据(参见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 )将数据发送到页面。
发布于 2015-04-07 19:42:52
当jQuery.ajax接收到时,火狐将内容代码的回调加载到页面代码(因为窗口/非安全窗口的设计?),所以您不再使用代码,而是在站点的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">
https://stackoverflow.com/questions/18200622
复制相似问题