js innerHTML 的一些问题的解决方法_javascript技巧

然而,你需要知道 innerHTML 有一些自身的问题: 

1、当 HTML 字符串包含一个标记为 defer 的 script 标签(<script defer>…</script>)时,如 innerHTML 属性处理不当,在 Internet Explorer 上会引起脚本注入攻击。 
2、设置 innerHTML 将会破坏现有的已注册了事件处理函数的 HTML 元素,会在某些浏览器上引起内存泄露的潜在危险。 

还有几个其他次要的缺点,也值得一提的: 

1、你不能得到刚刚创建的元素的引用,需要你手动添加代码才能取得那些引用(使用 DOM APIs)。 
2、你不能在所有浏览器的所有 HTML 元素上设置 innerHTML 属性(比如,Internet Explorer 不允许你在表格的行元素上设置innerHTML 属性)。 
我更关注与使用 innerHTML 属性相关的安全和内存问题。很显然,这不是新问题,已经有能人围绕这些中的某些问题想出了方法。 

       Douglas Crockford 写了一个 清除函数 ,该函数负责中止由于 HTML 元素注册事件处理函数引起的一些循环引用,并允许垃圾回收器(garbage collector)释放与这些 HTML 元素关联的内存。 

       从 HTML 字符串中移除 script 标签并不像看上去那么容易。一个正则表达式可以达到预期效果,虽然很难知道是否覆盖了所有的可能性。这里是我的解决方案: 
/<script[^>]*>[\S\s]*?<\/script[^>]*>/ig
现在,让我们将这两种技术结合在到一个单独的 setInnerHTML 函数中,并将 setInnerHTML 函数绑定到 YUI 的 YAHOO.util.Dom 上:
YAHOO.util.Dom.setInnerHTML = function (el, html) {
    el = YAHOO.util.Dom.get(el);
    if (!el || typeof html !== 'string') {
        return null;
    } 
    // 中止循环引用
    (function (o) {

        var a = o.attributes, i, l, n, c;
        if (a) {
            l = a.length;
            for (i = 0; i < l; i += 1) {
                n = a[i].name;
                if (typeof o[n] === 'function') {
                    o[n] = null;
                }
            }
        }

        a = o.childNodes;

        if (a) {
            l = a.length;
            for (i = 0; i < l; i += 1) {
                c = o.childNodes[i];

                // 清除子节点
                arguments.callee(c);

                // 移除所有通过YUI的addListener注册到元素上所有监听程序
                YAHOO.util.Event.purgeElement(c);
            }
        }

    })(el);

    // 从HTML字符串中移除script,并设置innerHTML属性
    el.innerHTML = html.replace(/<script[^>]*>[\S\s]*?<\/script[^>]*>/ig, "");

    // 返回第一个子节点的引用
    return el.firstChild;
};

如果此函数还应有其他任何内容或者在正则表达式中遗漏了什么,请让我知道。 

       很明显,在网页上还有很多其他注入恶意代码的方法。setInnerHTML 函数仅能在所有 A-grade 浏览器上规格化 <script> 标签的执行行为。如果你准备注入不能信任的 HTML 代码,务必首先在服务器端过滤,已有许多库可以做到这点。

时间: 2016-06-22
Tags: innerhtml

js innerHTML 的一些问题的解决方法_javascript技巧的相关文章

基于bootstrap-datetimepicker.js不支持IE8的快速解决方法_javascript技巧

实例如下: if (!Array.prototype.indexOf) Array.prototype.indexOf = function (elt /*, from*/) { var len = this.length >>> 0; var from = Number(arguments[1]) || 0; from = (from < 0) ? Math.ceil(from) : Math.floor(from); if (from < 0) from += len;

js中style.display=&quot;&quot;无效的解决方法_javascript技巧

本文实例讲述了js中style.display=""无效的解决方法.分享给大家供大家参考.具体解决方法如下: 一.问题描述: 在js中我们有时想动态的控制一个div显示或隐藏或更多的操作,但如果我们style.display=""可能导致没有效果. 看下面一段代码: 复制代码 代码如下: <style>  #name  {      display:none;  } </style> </head> <body> &l

Js,alert出现乱码问题的解决方法_javascript技巧

前些天还可以正常使用的js文件,在添加了一些东西后,其中的alert()弹出提示框总是中文乱码,在网上看了很多,给出的答案基本上是加一个<meta http-equiv="Content-Type" content="text/html;charset=gb2312" /> 或者是将gb2312换成utf-8,我用多种方法测了很久还是没能解决这问题. 解决方法:最后终于在某个论坛的一个角落里发现了点东西,原来在html里面引用js文件时要指定字符集的编码

js ajaxfileupload.js上传报错的解决方法_javascript技巧

相信大家在工作中经常用到文件上传的操作,因为我是搞前端的,所以这里主要是介绍ajax在前端中的操作.代码我省略的比较多,直接拿js那里的 $.ajaxFileUpload({ url:'www.coding/mobi/file/uploadSingleFile.html',//处理图片脚本 secureuri :false, fileElementId :'image2',//file控件id.就是input type="file" id="image2" data

transport.js和jquery冲突问题的解决方法_javascript技巧

问题原因:/js/transport.js 文件 Object.prototype.toJSONString = function () {**************} 大概 580行到590行之间 这个句用于格式化json,他重写了object的结构,导致于js框架冲突,如果要解决需要把这段代码注释掉,然后用别的方式替换. 我是将所有用到*.toJSONString的地方,替换成一个函数,例如: /js/common.js 29行 Ajax.call('flow.php?step=add_t

动态创建script在IE中缓存js文件时导致编码的解决方法_javascript技巧

先看下重现代码 1, gb2312.html 该文件编码为gb2312 复制代码 代码如下: <!DOCTYPE html> <html> <head> <title></title> <meta charset="gb2312"/> <style> p { color: red; } </style> </head> <body> <button onclic

js获取对象为null的解决方法_javascript技巧

页面上动态输出的数据,这是ajax获取的数据我要在页面上展示 复制代码 代码如下:     success:function(data){          var arr = data.split('_');          var numArr = arr[0].split(",");          var numStr = "";          if(numArr.length==undefined || numArr.length==0){    

Ajax局部更新导致JS事件重复触发问题的解决方法_javascript技巧

如果在页面中包含一个ajax更新的列表,那么需要小心非动态更新部分的事件处理. 以带有公共工具栏的列表界面为例: | Menu1 | Menu2 ---------------------------------------------------------------------------- ID TITLE DESCRIPTION OPERATION 1 test1 hey test X - ... 2 test2 why not X - ... --------------------

JS传值出现中文参数乱码的解决方法_javascript技巧

本文实例讲述了JS传值出现中文参数乱码的解决方法.分享给大家供大家参考,具体如下: function PopupFK(cNum,type){ var url = "contract!Paying.action"; url = url + "?contract.contractNum="+cNum+"&payingType="+type; // if(isEmpty($(_this).attr("payId"))){ /