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 相关文章推荐
Javascript 面向对象(三)接口代码
May 23 Javascript
中止javascript执行的方法
Feb 14 Javascript
手机端转盘抽奖代码分享
Sep 10 Javascript
JavaScript如何获取数组最大值和最小值
Nov 18 Javascript
基于jQuery实现拖拽图标到回收站并删除功能
Nov 25 Javascript
JS中创建函数的三种方式及区别
Mar 13 Javascript
微信小程序 开发指南详解
Sep 27 Javascript
让你彻底掌握es6 Promise的八段代码
Jul 26 Javascript
Web技术实现移动监测的介绍
Sep 18 Javascript
React 全自动数据表格组件——BodeGrid的实现思路
Jun 12 Javascript
vue 解决异步数据更新问题
Oct 29 Javascript
从零使用TypeScript开发项目打包发布到npm
Feb 14 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
解析smarty模板中类似for的功能实现
2013/06/18 PHP
Thinkphp和onethink实现微信支付插件
2016/04/13 PHP
PHP最常用的正则表达式
2017/02/13 PHP
详解PHP中的 input属性(隐藏 只读 限制)
2017/08/14 PHP
PHP实现简易图形计算器
2020/08/28 PHP
JS 实现双色表格实现代码
2009/11/24 Javascript
文本框的字数限制功能jquery插件
2009/11/24 Javascript
JavaScript Event学习第十章 一些可替换的事件对
2010/02/10 Javascript
jQuery 打造动态渐变按钮 详细图文教程
2010/04/25 Javascript
使用jquery实现图文切换效果另加特效
2013/01/20 Javascript
Javascript验证用户输入URL地址是否为空及格式是否正确
2014/10/09 Javascript
node.js中的fs.open方法使用说明
2014/12/17 Javascript
jquery实现炫酷的叠加层自动切换特效
2015/02/01 Javascript
为什么JS中eval处理JSON数据要加括号
2015/04/13 Javascript
JavaScript中模拟实现jsonp
2015/06/19 Javascript
理解Angular数据双向绑定
2016/01/10 Javascript
webstrom Debug 调试vue项目的方法步骤
2018/07/17 Javascript
vue中el-upload上传图片到七牛的示例代码
2018/10/19 Javascript
JS XMLHttpRequest原理与使用方法深入详解
2020/04/30 Javascript
vue如何搭建多页面多系统应用
2020/06/17 Javascript
深入理解Python分布式爬虫原理
2017/11/23 Python
Python通过属性手段实现只允许调用一次的示例讲解
2018/04/21 Python
python 给DataFrame增加index行名和columns列名的实现方法
2018/06/08 Python
python框架中flask知识点总结
2018/08/17 Python
pyqt5 使用cv2 显示图片,摄像头的实例
2019/06/27 Python
Python 可变类型和不可变类型及引用过程解析
2019/09/27 Python
python 画条形图(柱状图)实例
2020/04/24 Python
关于CSS Tooltips(鼠标经过时显示)的效果
2013/04/10 HTML / CSS
有原因的手表:Flex Watches
2019/03/23 全球购物
岳父生日宴会答谢词
2014/01/13 职场文书
给儿子的表扬信
2014/01/15 职场文书
2014年道德讲堂实施方案
2014/03/05 职场文书
少先队学雷锋活动总结范文
2014/03/09 职场文书
教师师德工作总结2015
2015/07/22 职场文书
深入浅析Redis 集群伸缩原理
2021/05/15 Redis
go使用Gin框架利用阿里云实现短信验证码功能
2021/08/04 Golang