【问题标题】:XMLHttpRequest.responseXML fires 'permission denied' exceptionXMLHttpRequest.responseXML 触发“权限被拒绝”异常
【发布时间】:2014-01-30 08:59:53
【问题描述】:

我正在开发一个需要支持 ajax 请求的 firefox 插件。请求将全部发送到“messagebeam.tagpulse.nl”域,因此我将其添加到 package.json 中的权限中,如下所示:

{
    "name": "messagebeam",
    "title": "Message Beam for Android™",
    "id": "jid1-j831e5AVhpvjDA",
    "description": "With one click bidirectionally beam anything you want between Chrome and your Android device!",
    "permissions": {
        "cross-domain-content": ["http://messagebeam.tagpulse.nl/"]
    },  
    "author": "TwZ",
    "license": "MPL 2.0",
    "version": "0.3"
}

到目前为止一切顺利。在我的 main.js 中,我定义了一个(非常基本的)小部件和一个面板(在 main.js 中)来演示问题:

var testPanel = require("sdk/panel").Panel({
  width:430,
  height:500,
  contentURL: data.url("test.html"),
  contentScriptFile: [
                        data.url('scripts/jquery-2.1.0.js'),
                        data.url('test.js')
                      ]
});
var widgets = require("sdk/widget");
var tabs = require("sdk/tabs");
var widget = widgets.Widget({
  id: "test-popup",
  label: "Message Beam",
  contentURL: data.url("img/test.png"),
  panel: testPanel
});

test.html 很基础(没有内容):

<html>
    <head>
    </head>
    <body>
        No content
    </body>
</html>

test.js(产生权限被拒绝错误的实际代码):

$(document).ready(function() {
    xmlhttp=new XMLHttpRequest();
    xmlhttp.onreadystatechange=function() {
        if (xmlhttp.readyState==4 && xmlhttp.status==200) {
            console.log('finished');
            console.log(xmlhttp.responseXML);
            console.log('reported xml');
        }
    }
    xmlhttp.open("GET","http://messagebeam.tagpulse.nl/test/test2.php",true);
    xmlhttp.send(); 
});

返回的xml如下(内容类型:text/xml响应头,使用http://messagebeam.tagpulse.nl/test/test2.php测试):

<?xml version="1.0" encoding="UTF-8" ?>
<test>
  text
</test>

现在的问题是:为什么console.log(xmlhttp.responseXML) 行会产生以下错误:

console.log: messagebeam: finished
System JS : ERROR resource://gre/modules/XPIProvider.jsm -> jar:file:///c:/users/js/appdata/local/temp/tmpfcjrsq.mozrunner/extensions/jid1-j831e5AVhpvjDA@jetpack.xpi!/bootstrap.js -> resource://gre/modules/commonjs/toolkit/loader.js -> resource://gre/modules/commonjs/sdk/loader/sandbox.js -> resource://gre/modules/commonjs/sdk/content/content-worker.js:81
                     Error: Permission denied to access property 'toJSON'

【问题讨论】:

    标签: ajax xmlhttprequest firefox-addon-sdk permission-denied


    【解决方案1】:

    首先查看错误消息中提到的代码行是个好主意。这是resource://gre/modules/commonjs/sdk/content/content-worker.js,第 81 行 - 这是集成到浏览器中的附加 SDK 代码。在 Firefox 26 中,这一行说:

    let str = JSON.stringify(args, replacer);
    

    此代码属于内容工作者的消息传递机制。 toJSON 在被序列化的对象上是 called implicitly by JSON.stringify

    显然,访问xmlhttp.responseXML 不会触发任何内容工作者事件。但是,console.log() 确实如此 - 在content-worker.js 中存在问题的createPipe 方法的正下方,您可以看到injectConsole 方法。这个为内容工作者提供console API,它将使用消息传递将任何调用转发到主扩展代码。

    此时问题应该很明显:即使“真正的”console.log() 方法可以处理 XMLDocument 类型的参数,但提供给内容工作者的方法却不能——它需要一个可以序列化为 JSON 的对象.但是,调用 console.log(xmlhttp.responseText) 应该可以。此外,console.log(new XMLSerializer.serializeToString(xmlhttp.responseXML)) 可能有效(我不确定 XMLSerializer constructor 是否在工作人员上下文中定义)。

    【讨论】:

    • 感谢您的详尽回答。这实际上是有道理的。但是,还有一个问题(非常相关)。我仍然无法“访问”responseXML。我制作了一个新的 Xml 文档并解析了 responseText 并且有效(即 console.log(xmlDoc.documentElement.childNodes[0].nodeValue); 显示“文本”,但在执行 console.log(xmlhttp.responseXML.childNodes[ 0].nodeValue); 仍然提出一个权限被拒绝(在 childNodes 上)。对此有什么想法吗?
    • @Toverbal:不,不是——听起来像是附加组件 SDK 使用的沙盒的副作用。可能值得filing as an Add-on SDK bug
    • 我会这样做的。我想知道他们是怎么想的。再次感谢!
    • 我已经提交了错误报告。你可以在这里找到它:bugzilla.mozilla.org/show_bug.cgi?id=966609
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-30
    相关资源
    最近更新 更多