现在,我正在使用用户脚本进行浏览器游戏。我在沙盒和初始化方面遇到了一些问题。
作为解决方案,我找到了一种创建新元素(脚本)并在元素中插入对象的方法。
var script = document.createElement("script");
script.type = "text/javascript";
script.innerHTML = "var Class = { ... }";
document.body.appendChild(script);
但是我有一个非常大的对象并将其转换为一个字符串,这很有问题且耗时。
我有一个看起来像这样的对象:
{
addToStorage : Function,
getFromStorage : Function,
getID : Function
settings : Object,
langs : Object,
init : Function,
version : Number,
author: String
}
任何想法,如何将其转换为字符串或插入到全局窗口中?
对不起,我的英语不好。
在 Firefox 中,你可以在对象上使用 .toSource()
函数。 所以答案是放弃Chrome并切换到Firefox。(^_^)
但是假设你不想这样做,答案就会变得混乱,因为如果对象作为函数属性,就像你一样,即使JSON.stringify()
也不起作用。
因此,您可以使用多行字符串注入对象源(有关各种技术,请参阅链接)。
或者你可以制作或使用一个对象字符串,如下面的objToString
。 警告,objToString
只是一个快速而肮脏的第一次尝试,你可能会更聪明地抓住像JavaScript var_export这样的东西。
var myObjX = {
someFunction: function () {console.log ("foo");},
settings: {init: 2},
langs: {a: "En", b: "Jp"},
version: 99,
author: "Anon"
}
function objToString (obj) {
var str = '{ ';
for (var p in obj) {
if (obj.hasOwnProperty (p) ) {
str += p + ': ';
switch (typeof obj[p]) {
case "object":
str += objToString (obj[p]);
break;
case "string":
str += '"' + obj[p] + '"';
break;
default:
str += obj[p];
break;
}
str += ',n';
}
}
return str.slice (0, str.length-2) + ' }';
}
var script = document.createElement("script");
script.type = "text/javascript";
script.textContent = "var injectedX = " + objToString (myObjX);
document.body.appendChild (script);
使用 unsafeWindow
对象冲出 greasemonkey 沙箱。
为了打破Chrome的隔离环境,根据Chrome用户脚本是否像Greasemonkey脚本一样与全局命名空间分离?您需要将<script>
元素插入DOM中。
您不应该将该脚本的源代码存储在转义字符串中,最好采用 JS 对象并将其字符串化。对于普通的,您可以使用 JSON
,对于更复杂的事情,将所有内容放入一个函数中并调用.toString()
:
function moduleClosure(global) {
// do something
return some object
}
var script = document.createElement("script");
script.type = "text/javascript";
script.innerText = "var Class = "+moduleClosure+"(window);";
document.body.appendChild(script);