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 相关文章推荐
Dojo 学习要点
Sep 03 Javascript
微博@符号的用户名提示效果。(想@到谁?)
Nov 05 Javascript
js对象的复制继承实例
Jan 10 Javascript
jQuery实现连续动画效果实例分析
Oct 09 Javascript
JavaScript动态插入CSS的方法
Dec 10 Javascript
H5移动端适配 Flexible方案
Oct 24 Javascript
JavaScript中最常用的10种代码简写技巧总结
Jun 28 Javascript
基于vue开发的在线付费课程应用过程
Jan 25 Javascript
vue+axios实现文件下载及vue中使用axios的实例
Sep 21 Javascript
javascript 原型与原型链的理解及实例分析
Nov 23 Javascript
JS可断点续传文件上传实现代码解析
Jul 30 Javascript
vue使用echarts图表自适应的几种解决方案
Dec 04 Vue.js
很酷的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中使用crypt()实现用户身份验证的代码
2012/09/05 PHP
解析ajax事件的调用顺序
2013/06/17 PHP
PHP迭代器实现斐波纳契数列的函数
2013/11/12 PHP
php 判断字符串中是否包含html标签
2014/02/17 PHP
php使用pdo连接并查询sql数据库的方法
2014/12/24 PHP
PHP将session信息存储到数据库的类实例
2015/03/04 PHP
php分割合并两个字符串的函数实例
2015/06/19 PHP
PHP实现接收二进制流转换成图片的方法
2017/01/10 PHP
jQuery 1.0.4 - New Wave Javascript(js源文件)
2007/01/15 Javascript
js jquery做的图片连续滚动代码
2008/01/06 Javascript
浅析js封装和作用域
2013/07/09 Javascript
地址栏传递中文参数乱码在js里用escape转码
2013/08/28 Javascript
js实现日历可获得指定日期周数及星期几示例分享(js获取星期几)
2014/03/14 Javascript
js实现带关闭按钮始终显示在网页最底部工具条的方法
2015/03/02 Javascript
用Node.js通过sitemap.xml批量抓取美女图片
2015/05/28 Javascript
对象转换为原始值的实现方法
2016/06/06 Javascript
给Easyui-Datebox设置隐藏或者不可用的解决方法
2017/05/26 Javascript
ES6中的rest参数与扩展运算符详解
2017/07/18 Javascript
vue使用axios上传文件(FormData)的方法
2019/04/14 Javascript
javascript删除数组元素的七个方法示例
2019/09/09 Javascript
Python中optionParser模块的使用方法实例教程
2014/08/29 Python
解决Matplotlib图表不能在Pycharm中显示的问题
2018/05/24 Python
python 检查文件mime类型的方法
2018/12/08 Python
对python csv模块配置分隔符和引用符详解
2018/12/12 Python
带你认识Django
2019/01/15 Python
Python分支语句与循环语句应用实例分析
2019/05/07 Python
在notepad++中实现直接运行python代码
2019/12/18 Python
Django框架教程之中间件MiddleWare浅析
2019/12/29 Python
使用pygame编写Flappy bird小游戏
2020/03/14 Python
python json.dumps() json.dump()的区别详解
2020/07/14 Python
基于HTML5 Canvas 实现商场监控实例详解
2017/11/20 HTML / CSS
bonprix荷兰网上商店:便宜的服装、鞋子和家居用品
2020/07/04 全球购物
2014年信访维稳工作总结
2014/12/08 职场文书
法律意见书范本
2015/06/04 职场文书
2015年公路路政个人工作总结
2015/07/24 职场文书
Go gorilla/sessions库安装使用
2022/08/14 Golang