我正在开发cross-browser extension for Battlelog(战地系列的在线游戏启动器和社交平台)。
为了使其正常运行,它需要访问页面的JS环境,因为整个网站是一个庞大而复杂的客户端应用程序,尝试复制它是没有意义的,而所有的功能我需要就在那里。
无论如何,我上周推出了一个工作扩展,并将其提交给AMO进行审核。几个小时前我收到了回复:
您的版本被拒绝了。您的加载项从HTML创建DOM节点 包含unsanitized数据的字符串,通过分配innerHTML或 通过类似的方式。除了效率低下,这是一个主要问题 安全风险。有关更多信息,请参阅 https://developer.mozilla.org/en/XUL_School/DOM_Building_and_HTML_Insertion
显然,这是因为this content script:
var head = document.getElementsByTagName('head')[0];
var css = document.createElement('link');
css.setAttribute('rel', 'stylesheet');
css.setAttribute('type', 'text/css');
css.setAttribute('href', @@CSS@@);
head.appendChild(css);
var js = document.createElement('script');
js.setAttribute('type', 'text/javascript');
js.setAttribute('src', @@JS@@);
head.appendChild(js);
虽然我同意,但它很脏,我不知道这是一种安全风险或任何方式效率低下。其中没有“未经过规范化”的数据:@@CSS@@
和@@JS@@
在构建过程中分别被self.data.url('battletag.css')
和self.data.url('battletag.js')
替换。
我正在寻找一种方法来扩展工作而不需要点击页面的上下文(当然这是可能的),但我真的不想这样做,特别是在途中有几个功能,大量使用页面数据。响应中提供的链接根本没用,因为我的注入脚本基本上是JSON模板的精简版本。
将JS文件加载到文档中是否有“合法”方式?
答案 0 :(得分:1)
你的代码看起来很好我不知道为什么拒绝它。
但他们想看到的是:
var injectJsonCss = [
'link', {
rel: 'stylesheet',
type: 'text/css',
href: 'chrome://your-path-set-in-the-chrome.manifest-file/content/your-style.css'
}
];
var injectJsonScript = [
'script', {
type: 'stylesheet',
type: 'text/javascript',
src: 'chrome://your-path-set-in-the-chrome.manifest-file/content/your-script.js'
}
];
jsonToDOM(injectJsonCss, document.head, {}); //inject the css
jsonToDOM(injectJsonScript, document.head, {}); //inject the script
确保该文档是网站的contentDocument
并在您的代码中粘贴从该页面中删除的库内容
jsonToDOM.namespaces = {
html: "http://www.w3.org/1999/xhtml",
xul: "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
};
jsonToDOM.defaultNamespace = jsonToDOM.namespaces.html;
function jsonToDOM(xml, doc, nodes) {
function namespace(name) {
var m = /^(?:(.*):)?(.*)$/.exec(name);
return [jsonToDOM.namespaces[m[1]], m[2]];
}
function tag(name, attr) {
if (Array.isArray(name)) {
var frag = doc.createDocumentFragment();
Array.forEach(arguments, function (arg) {
if (!Array.isArray(arg[0]))
frag.appendChild(tag.apply(null, arg));
else
arg.forEach(function (arg) {
frag.appendChild(tag.apply(null, arg));
});
});
return frag;
}
var args = Array.slice(arguments, 2);
var vals = namespace(name);
var elem = doc.createElementNS(vals[0] || jsonToDOM.defaultNamespace,
vals[1]);
for (var key in attr) {
var val = attr[key];
if (nodes && key == "key")
nodes[val] = elem;
vals = namespace(key);
if (typeof val == "function")
elem.addEventListener(key.replace(/^on/, ""), val, false);
else
elem.setAttributeNS(vals[0] || "", vals[1], val);
}
args.forEach(function(e) {
elem.appendChild(typeof e == "object" ? tag.apply(null, e) :
e instanceof Node ? e : doc.createTextNode(e));
});
return elem;
}
return tag.apply(null, xml);
}
您是否使用script.js中的脚本设置任何innerHTML?