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 读取元素的CSS信息的代码
Feb 07 Javascript
jQuery Pagination Ajax分页插件(分页切换时无刷新与延迟)中文翻译版
Jan 11 Javascript
jQuery :first选择器使用介绍
Aug 09 Javascript
sliderToggle在写jquery的计时器setTimeouter中不生效
May 26 Javascript
node.js中的path.resolve方法使用说明
Dec 08 Javascript
JQuery实现的购物车功能(可以减少或者添加商品并自动计算价格)
Jan 13 Javascript
jQuery插件formValidator实现表单验证
May 23 Javascript
Vuejs第七篇之Vuejs过渡动画案例全面解析
Sep 05 Javascript
html判断当前页面是否在iframe中的实例
Nov 30 Javascript
jQuery+HTML5实现弹出创意搜索框层
Dec 29 Javascript
Vue.js 点击按钮显示/隐藏内容的实例代码
Feb 08 Javascript
详解json串反转义(消除反斜杠)
Aug 12 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写的简易聊天室代码
2011/06/04 PHP
Pain 全世界最小最简单的PHP模板引擎 (普通版)
2011/10/23 PHP
php另类上传图片的方法(PHP用Socket上传图片)
2013/10/30 PHP
php用正则表达式匹配中文实例详解
2013/11/06 PHP
codeigniter框架批量插入数据
2014/01/09 PHP
WordPress中用于创建以及获取侧边栏的PHP函数讲解
2015/12/29 PHP
thinkphp3.2实现在线留言提交验证码功能
2017/07/19 PHP
Discuz不使用插件实现简单的打赏功能
2019/03/21 PHP
再谈ie和firefox下的document.all属性
2009/10/21 Javascript
理解Javascript_13_执行模型详解
2010/10/20 Javascript
基于Angularjs实现分页功能
2016/05/30 Javascript
Ubuntu 16.04 64位中搭建Node.js开发环境教程
2016/10/19 Javascript
浅谈html转义及防止javascript注入攻击的方法
2016/12/04 Javascript
Bootstrap路径导航与分页学习使用
2017/02/08 Javascript
详解Vue中状态管理Vuex
2017/05/11 Javascript
js遍历添加栏目类添加css 再点击其它删除css【推荐】
2018/06/12 Javascript
vue2.0$nextTick监听数据渲染完成之后的回调函数方法
2018/09/11 Javascript
微信小程序实现日历效果
2018/12/28 Javascript
图文讲解vue的v-if使用方法
2019/02/11 Javascript
JavaScript在web自动化测试中的作用示例详解
2019/08/25 Javascript
JS数组的高级使用方法示例小结
2020/03/14 Javascript
js+css3实现简单时钟特效
2020/09/13 Javascript
使用python BeautifulSoup库抓取58手机维修信息
2013/11/21 Python
Python实现多线程下载文件的代码实例
2014/06/01 Python
Python程序中使用SQLAlchemy时出现乱码的解决方案
2015/04/24 Python
Python/ArcPy遍历指定目录中的MDB文件方法
2018/10/27 Python
PyQt编程之如何在屏幕中央显示窗体的实例
2019/06/18 Python
Python中使用gflags实例及原理解析
2019/12/13 Python
Python:type、object、class与内置类型实例
2019/12/25 Python
解决Pycharm双击图标启动不了的问题(JetBrains全家桶通用)
2020/08/07 Python
协程Python 中实现多任务耗资源最小的方式
2020/10/19 Python
amazeui时间组件的实现示例
2020/08/18 HTML / CSS
如何利用cmp命令比较文件
2013/09/23 面试题
cf搞笑广告词
2014/03/14 职场文书
2014年实验室工作总结
2014/12/03 职场文书
go select编译期的优化处理逻辑使用场景分析
2021/06/28 Golang