json html的安全方式?

时间:2016-03-17 23:43:06

标签: javascript html json

我的问题很简单,我想用json重新创建一个html页面, 但我不想搞乱现有的HTML,框架和合作......

示例:

var myDiv = { tag : "div", style : "color:blue", class : "jj", content : "Hello"};

var myDiv = { tag : "div", style : "color:blue", class : "jj", content : "Hello"};
var param = { forbid : { tag : true, content : true } };
var createTag = function(o) {

    var node = document.createElement(o.tag);
    for (att in o) {
      if (!param.forbid[att]) node.setAttribute(att, o[att]);
    }
    node.appendChild(document.createTextNode(o.content))
    return node;

}


document.body.textContent = createTag(myDiv).outerHTML;

此代码的结果是:

<div style="color:blue" class="jj"> Hello </div>

我如何确定“标记”和“内容”不会混淆现有/未来的属性? 保持简单?

2 个答案:

答案 0 :(得分:9)

为避免与属性冲突,我会将它们分开

var myDiv = {
  tagName: "div",
  attributes: {
    style: "color: blue",
    class: "jj"
  },
  childNodes: ["Hello"]
};

&#13;
&#13;
function parseTree(node) {
  if(typeof node === 'string') // Text node
    return document.createTextNode(node);
  // Otherwise, assuming an element. Consider adding
  // `node.nodeType` if you want multiple node types
  var el = document.createElement(node.tagName);
  if(node.hasOwnProperty('attributes'))
    for(var attr in node.attributes)
      if(node.attributes.hasOwnProperty(attr))
        el.setAttribute(attr, node.attributes[attr]);
  if(node.hasOwnProperty('childNodes'))
    node.childNodes.forEach(function(child) {
      el.appendChild(parseTree(child));
    });
  return el;
}
document.body.textContent = parseTree({
  tagName: "div",
  attributes: {
    style: "color: blue",
    class: "jj"
  },
  childNodes: ["Hello"]
}).outerHTML;
&#13;
&#13;
&#13;

或者,您可以使用字符串,其中包含属性名称中不允许的某些字符。例如,\u0000

var myDiv = {
  " tagName": "div",
  style: "color: blue",
  class: "jj",
  " childNodes": ["Hello"]
};

&#13;
&#13;
function parseTree(node) {
  if(typeof node === 'string') // Text node
    return document.createTextNode(node);
  // Otherwise, assuming an element. Consider adding
  // `node[" nodeType"]` if you want multiple node types
  var el = document.createElement(node[" tagName"]);
  for(var attr in node)
    if(node.hasOwnProperty(attr) && attr[0] !== " ")
      el.setAttribute(attr, node[attr]);
  if(node[" childNodes"])
    node[" childNodes"].forEach(function(child) {
      el.appendChild(parseTree(child));
    });
  return el;
}
document.body.textContent = parseTree({
  " tagName": "div",
  style: "color: blue",
  class: "jj",
  " childNodes": ["Hello"]
}).outerHTML;
&#13;
&#13;
&#13;

答案 1 :(得分:-1)

如果您愿意,可以尝试这样的事情:

["div", {style: "color:blue", class: "jj"}, ["Hello"]]

使用内部元素,您可以:

["div", {style: "color:blue", class: "jj"}, [[
  "p",
  "hello"
]]]

这里是解析代码(只是parseTree函数) - 我还添加了一种尝试方法(并且以基于json的格式编写HTML作为示例)

&#13;
&#13;
html = ["div", [["div",
  [
    ["p", ["Try it out:"]],
    [
      "code", {
        id: "try",
        style: "display:block",
        contentEditable: true
      },
      ['["div", { style: "color:blue;", class: "jj"}, ["Hello"]]']
    ],
    ["button", {
        "onclick": "return tryOut();"
      },
      ["Run"]
    ]
  ]
],["div", {id: "result-wrapper"}]]]

window.tryOut = function() {
  var el = parseTree(eval(document.querySelector("code#try").innerText));
  var holder = document.createElement("div");
  holder.appendChild(el);
  document.querySelector("#result-wrapper").innerHTML = holder.innerHTML;
}

document.body.appendChild(parseTree(html));


function parseTree(tree) {
  if (typeof tree === 'string') {
    return document.createTextNode(tree);
  }

  var el = document.createElement(tree[0]),
    attrs, simple, inner;

  if (tree.length == 2) {
    if (Array.isArray(tree[1])) {
      inner = tree[1];
    } else {
      attrs = tree[1];
    }
  } else if (tree.length == 3) {
    attrs = tree[1];
    inner = tree[2];
  } else {
    simple = true;
  }

  if (!simple) {
    if (attrs) {
      for (var attr in attrs)
        if (attrs.hasOwnProperty(attr)) {
          console.log(attr)
          console.log(attrs[attr])
          el.setAttribute(attr, attrs[attr]);
        }
    }
    if (inner) {
      inner.forEach(function(child) {
        el.appendChild(parseTree(child));
      });
    }
  }

  return el;
}

if (!Array.isArray) {
  Array.isArray = function(arg) {
    return Object.prototype.toString.call(arg) === '[object Array]';
  };
}
&#13;
&#13;
&#13;