js innerHTML 的一些问题的解决方法


Posted in Javascript onJune 22, 2008

然而,你需要知道 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 代码,务必首先在服务器端过滤,已有许多库可以做到这点。

Javascript 相关文章推荐
传智播客学习之java 反射
Nov 22 Javascript
JS 退出系统并跳转到登录界面的实现代码
Jun 29 Javascript
JavaScript实现cookie的写入、读取、删除功能
Nov 05 Javascript
javascript中的作用域和闭包详解
Jan 13 Javascript
学习Javascript面向对象编程之封装
Feb 23 Javascript
jquery实现左右无缝轮播图
Jul 31 Javascript
详谈JS中实现种子随机数及作用
Jul 19 Javascript
JavaScript表单验证实现代码
May 22 Javascript
JavaScript数据结构之双向链表和双向循环链表的实现
Nov 28 Javascript
微信小程序前端promise封装代码实例
Aug 24 Javascript
Vue在chrome44偶现点击子元素事件无法冒泡的解决方法
Dec 15 Javascript
js实现简单的打印表格
Jan 15 Javascript
很酷的javascript loading效果代码
Jun 18 #Javascript
豆瓣网的jquery代码实例
Jun 15 #Javascript
JQuery实现自定义对话框的代码
Jun 15 #Javascript
javascript基本语法分析说明
Jun 15 #Javascript
javascript新手语法小结
Jun 15 #Javascript
JavaScript入门学习书籍推荐
Jun 12 #Javascript
asp.net和asp下ACCESS的参数化查询
Jun 11 #Javascript
You might like
php ajax异步读取rss文档数据
2016/03/29 PHP
PHP论坛实现积分系统的思路代码详解
2020/06/01 PHP
不提示直接关闭网页窗口的JS示例代码
2013/12/17 Javascript
Jquery 获取指定标签的对象及属性的设置与移除
2014/05/29 Javascript
Javascript基础知识(一)核心基础语法与事件模型
2014/09/29 Javascript
AngularJS入门教程之学习环境搭建
2014/12/06 Javascript
JavaScript实现模仿桌面窗口的方法
2015/07/18 Javascript
js判断手机系统是android还是ios
2017/03/07 Javascript
微信小程序开发之入门实例教程篇
2017/03/07 Javascript
JavaScript选择排序算法原理与实现方法示例
2018/08/06 Javascript
vue项目在安卓低版本机显示空白的原因分析(两种)
2018/09/04 Javascript
详解vue-router导航守卫
2019/01/19 Javascript
在Vue项目中使用jsencrypt.js对数据进行加密传输的方法
2019/04/17 Javascript
ajaxfileupload.js实现上传文件功能
2019/04/19 Javascript
Vue中消息横向滚动时setInterval清不掉的问题及解决方法
2019/08/23 Javascript
浅析Vue下的components模板使用及应用
2019/11/27 Javascript
vue实现的多页面项目如何优化打包的步骤详解
2020/07/19 Javascript
python实现从ftp服务器下载文件的方法
2015/04/30 Python
小小聊天室Python代码实现
2016/08/17 Python
PyTorch上实现卷积神经网络CNN的方法
2018/04/28 Python
python3 爬取图片的实例代码
2018/11/06 Python
python使用循环打印所有三位数水仙花数的实例
2018/11/13 Python
解决django中ModelForm多表单组合的问题
2019/07/18 Python
python正则-re的用法详解
2019/07/28 Python
python实现身份证实名认证的方法实例
2019/11/08 Python
python读取excel进行遍历/xlrd模块操作
2020/07/12 Python
python pip如何手动安装二进制包
2020/09/30 Python
信息技术毕业生自荐信范文
2014/03/13 职场文书
2014年干部培训工作总结
2014/12/17 职场文书
汇报材料怎么写
2014/12/30 职场文书
平凡的世界读书笔记
2015/06/25 职场文书
感恩的心主题班会
2015/08/12 职场文书
导游词之无锡华莱坞
2019/12/02 职场文书
Apache Calcite 实现方言转换的代码
2021/04/24 Servers
教你使用Python获取QQ音乐某个歌手的歌单
2022/04/03 Python
Spring Cloud OAuth2实现自定义token返回格式
2022/06/25 Java/Android