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中清空数组的三种方法分享
Apr 07 Javascript
js 代码优化点滴记录
Feb 19 Javascript
js实现漂浮回顶部按钮实例
May 06 Javascript
JavaScript模拟鼠标右键菜单效果
Dec 08 Javascript
javascript实现数字倒计时特效
Mar 30 Javascript
Node.js Mongodb 密码特殊字符 @的解决方法
Apr 11 Javascript
JQuery实现table中tr上移下移的示例(超简单)
Jan 08 jQuery
Angular4学习笔记router的简单使用
Mar 30 Javascript
创建echart多个联动的示例代码
Nov 23 Javascript
详解Angular Forms中自定义ngModel绑定值的方式
Dec 10 Javascript
解决Layui当中的导航条动态添加后渲染失败的问题
Sep 25 Javascript
在vue中axios设置timeout超时的操作
Sep 04 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 header下载函数
2014/01/31 PHP
Yii实现MySQL多数据库和读写分离实例分析
2014/12/03 PHP
pjblog中的UBBCode.js
2007/04/25 Javascript
javascript 获取元素位置的快速方法 getBoundingClientRect()
2009/11/26 Javascript
Mac/Windows下如何安装Node.js
2013/11/22 Javascript
浅谈jQuery异步对象(XMLHttpRequest)
2014/11/17 Javascript
javascript中in运算符用法分析
2015/04/28 Javascript
基于jQuery实现文本框只能输入数字(小数、整数)
2016/01/14 Javascript
JavaScript焦点事件、鼠标事件和滚轮事件使用详解
2016/01/15 Javascript
解析Javascript单例模式概念与实例
2016/12/05 Javascript
js仿小米手机上下滑动效果
2017/02/05 Javascript
使用jQuery卸载全部事件的思路详解
2017/04/03 jQuery
JS组件系列之MVVM组件 vue 30分钟搞定前端增删改查
2017/04/28 Javascript
微信小程序视图template模板引用的实例详解
2017/09/20 Javascript
bootstrap中selectpicker下拉框使用方法实例
2018/03/22 Javascript
Auto.js自动收取自己和好友蚂蚁森林能量脚本
2018/06/28 Javascript
浅谈Angularjs中不同类型的双向数据绑定
2018/07/16 Javascript
vue完成项目后,打包成静态文件的方法
2018/09/03 Javascript
vue实现动态列表点击各行换色的方法
2018/09/13 Javascript
在Vant的基础上实现添加表单验证框架的方法示例
2018/12/05 Javascript
100行代码实现vue表单校验功能(小白自编)
2019/11/19 Javascript
vue实现的封装全局filter并统一管理操作示例
2020/02/02 Javascript
vue界面发送表情的实现代码
2020/09/11 Javascript
[01:07:20]DOTA2-DPC中国联赛 正赛 Dynasty vs XG BO3 第二场 2月2日
2021/03/11 DOTA
python中合并两个文本文件并按照姓名首字母排序的例子
2014/04/25 Python
跟老齐学Python之坑爹的字符编码
2014/09/28 Python
python 字典(dict)按键和值排序
2016/06/28 Python
python smtplib模块自动收发邮件功能(二)
2018/05/22 Python
python3实现小球转动抽奖小游戏
2020/04/15 Python
NEW LOOK官网:英国时装零售巨头之一,快时尚品牌
2017/01/11 全球购物
英国历史最悠久的DJ设备供应商:DJ Finance、DJ Warehouse、The DJ Shop
2019/09/04 全球购物
浅谈react路由传参的几种方式
2021/03/23 Javascript
一名毕业生的自我鉴定
2013/12/04 职场文书
《守株待兔》教学反思
2014/03/01 职场文书
校庆团日活动总结
2014/08/28 职场文书
js 实现Material UI点击涟漪效果示例
2022/09/23 Javascript