Firefox nsIProtocolHandler和nsIURI:自创协议中的相对URL
我有一个自定义协议的简单实现。据说newURI方法接受3个参数(spec、charset和baseURI),并且“如果协议没有相对uri的概念,则忽略第三个参数” 所以我打开一个这样的页面tada://domain/samplepage 其中包含以以下内容开头的XML:Firefox nsIProtocolHandler和nsIURI:自创协议中的相对URL,firefox,firefox-addon,xpcom,Firefox,Firefox Addon,Xpcom,我有一个自定义协议的简单实现。据说newURI方法接受3个参数(spec、charset和baseURI),并且“如果协议没有相对uri的概念,则忽略第三个参数” 所以我打开一个这样的页面tada://domain/samplepage 其中包含以以下内容开头的XML: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE Product SYSTEM "product.dtd"> 从newChannel返回的频道具有传递给n
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Product SYSTEM "product.dtd">
从newChannel返回的频道具有传递给
newChannelFromURI
的chrome://
URI作为其URI。这就是页面的URI,作为它的URI,作为它的基本URI。因此,DTD负载发生在“chrome://my-extension/content/about/product.dtd“直接
您可能想做的是将aURI设置为您从newChannel返回的频道上的originalURI。正如Boris在回答中提到的那样,您的协议实现没有设置
nsIChannel.originalURI
属性,因此URL将相对于chrome:
URL解析,而不是相对于tada:
URL解析。但是,您的代码还有第二个问题:在Firefox中,加载外部DTD仅适用于chrome:
URL,此检查是硬编码的。映射到本地文件(各种HTML文档类型)的受支持DTD数量有限,但仅此而已-Gecko不支持
中的随机URL。您可以在中看到当前逻辑。相关的bug是无法修复的。Boris和Wladimir,谢谢
过了一段时间,我有了一个解决办法。问题是无法从自定义创建的协议加载DTD文件。其思想是使用代理API重写schemeIs()方法,该方法在nsIProtocolHandler的newURI方法中调用
现在我在newURI方法中有了这段代码:
let standardUrl = Cc["@mozilla.org/network/standard-url;1"].createInstance(Ci.nsIStandardURL);
standardUrl.init(standardUrl.URLTYPE_STANDARD, -1, spec, charset, baseURI);
standardUrl.QueryInterface(Ci.nsIURL);
return Proxy.create(proxyHandlerMaker(standardUrl));
只需实现代理API并重写所需的schemeIs()方法。这就解决了问题,现在所有的请求都来到了newChannel,我们可以在那里处理它们
重要提示:
嗯。。。这是什么?我在中找不到此属性
let standardUrl = Cc["@mozilla.org/network/standard-url;1"].createInstance(Ci.nsIStandardURL);
standardUrl.init(standardUrl.URLTYPE_STANDARD, -1, spec, charset, baseURI);
standardUrl.QueryInterface(Ci.nsIURL);
return Proxy.create(proxyHandlerMaker(standardUrl));