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

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

(0)

相关推荐

  • javascript innerHTML、outerHTML、innerText、outerText的区别

    1.功能讲解: innerHTML 设置或获取位于对象起始和结束标签内的 HTML outerHTML 设置或获取对象及其内容的 HTML 形式 innerText 设置或获取位于对象起始和结束标签内的文本 outerText 设置(包括标签)或获取(不包括标签)对象的文本 2.示例 <html> <head> <title>Demo</title> <style><!-- body {font-family:"宋体";

  • JS中innerHTML和pasteHTML的区别实例分析

    本文实例讲述了JS中innerHTML和pasteHTML的区别.分享给大家供大家参考,具体如下: innerHTML 是一个属性,可以取得或者设定该元素内的 HTML 内容,可以是任意能包含 HTML 子节点的元素都使用它 pasteHTML()是一个方法,在指定的文字区域内替换该区域内的文本或者HTML,该方法必须应用于一个 createTextRange() 或者 document.selection.createRange() 创建的区域上 例: <Script Language="

  • JS实现pasteHTML兼容ie,firefox,chrome的方法

    本文实例讲述了JS实现pasteHTML兼容ie,firefox,chrome的方法.分享给大家供大家参考,具体如下: <html> <body> <script language="JavaScript"> function test() { if (document.selection && document.selection.createRange) { var myRange = document.selection.cre

  • javascript 异步的innerHTML使用分析

    当然,这个分时加载技术只是一个辅助技术,本身没有添加节点的能力.如今,另一种更奇特的技术Asynchronous innerHTML又被开发出来了,不能不赞一下外国人在这方面研究是非常超前的. 复制代码 代码如下: function asyncInnerHTML(HTML, callback) { var temp = document.createElement('div'), frag = document.createDocumentFragment(); temp.innerHTML =

  • javascript innerHTML使用分析

    空格处理 当在DIV中输入"a[任意个空格]a" HTML呈现在Chrome和IE下是一样的:只显示一个空格. innerHTML属性 IE还是两个a加一个空格, Chrome则是原始输入的样子. 回车 当在DIV中输入"a[回车][任意个空格]a"时,HTML呈现Chrome和IE是一样的. innerHTML属性 IE是3个字符,在两个a中间加了个空格. Chrome则是原始输入的样子,将回车解析为\n. HTML标记 当在DIV中输入"a<Br

  • JavaScript中innerHTML,innerText,outerHTML的用法及区别

    不废话了,请看下文示例介绍. 用法: <div id="test"> <span style="color:red">test1</span> test2 </div> 在JS中可以使用: test.innerHTML: 也就是从对象的起始位置到终止位置的全部内容,包括Html标签. 上例中的test.innerHTML的值也就是"<span style="color:red">

  • js innerHTML 改变div内容的方法

    改变文字innerHTML每个HTML元素具有InnerHtml属性定义的HTML代码和文字之间发生的元素的开幕式和闭幕式标记.通过改变一个元素的innerHTML后,一些用户交互,您可以更互动网页.但是,使用innerHTML需要一些准备,如果你希望能够利用它轻松,可靠.首先,你必须给予部分要更改身份证.与标识到位,你将能够使用getElementById功能,适用于所有的浏览器.在您认为建立您现在就可以操纵文字的要素.要开始了,让我们尝试改变文字一个大胆的标记.下面我们来看一个用js的inn

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

    然而,你需要知道 innerHTML 有一些自身的问题: 1.当 HTML 字符串包含一个标记为 defer 的 script 标签(<script defer>-</script>)时,如 innerHTML 属性处理不当,在 Internet Explorer 上会引起脚本注入攻击.  2.设置 innerHTML 将会破坏现有的已注册了事件处理函数的 HTML 元素,会在某些浏览器上引起内存泄露的潜在危险. 还有几个其他次要的缺点,也值得一提的: 1.你不能得到刚刚创建的元素

  • 基于bootstrap-datetimepicker.js不支持IE8的快速解决方法

    实例如下: if (!Array.prototype.indexOf) Array.prototype.indexOf = function (elt /*, from*/) { var len = this.length >>> 0; var from = Number(arguments[1]) || 0; from = (from < 0) ? Math.ceil(from) : Math.floor(from); if (from < 0) from += len;

  • js中style.display=""无效的解决方法

    本文实例讲述了js中style.display=""无效的解决方法.分享给大家供大家参考.具体解决方法如下: 一.问题描述: 在js中我们有时想动态的控制一个div显示或隐藏或更多的操作,但如果我们style.display=""可能导致没有效果. 看下面一段代码: 复制代码 代码如下: <style>  #name  {      display:none;  } </style> </head> <body> &l

  • Js,alert出现乱码问题的解决方法

    前些天还可以正常使用的js文件,在添加了一些东西后,其中的alert()弹出提示框总是中文乱码,在网上看了很多,给出的答案基本上是加一个<meta http-equiv="Content-Type" content="text/html;charset=gb2312" /> 或者是将gb2312换成utf-8,我用多种方法测了很久还是没能解决这问题. 解决方法:最后终于在某个论坛的一个角落里发现了点东西,原来在html里面引用js文件时要指定字符集的编码

  • transport.js和jquery冲突问题的解决方法

    问题原因:/js/transport.js 文件 Object.prototype.toJSONString = function () {**************} 大概 580行到590行之间 这个句用于格式化json,他重写了object的结构,导致于js框架冲突,如果要解决需要把这段代码注释掉,然后用别的方式替换. 我是将所有用到*.toJSONString的地方,替换成一个函数,例如: /js/common.js 29行 Ajax.call('flow.php?step=add_t

  • jquery与js函数冲突的两种解决方法

    如果您还有别的要求,想继续使用原先的$(),同时还需要与别的类库不冲突的话,还有两种解决方法 其一: 复制代码 代码如下: jQuery.noConflict(); jQuery(function($) { $("p").click(function() //在函数内继续可以使用jquery类库的$()方法 { alert($(this).text()); }) }) var JsCOM_cr = $("cr"); // 在函数外面,照样可以使用JsCOM.js的$

  • js ajaxfileupload.js上传报错的解决方法

    相信大家在工作中经常用到文件上传的操作,因为我是搞前端的,所以这里主要是介绍ajax在前端中的操作.代码我省略的比较多,直接拿js那里的 $.ajaxFileUpload({ url:'www.coding/mobi/file/uploadSingleFile.html',//处理图片脚本 secureuri :false, fileElementId :'image2',//file控件id.就是input type="file" id="image2" data

  • js跨域问题浅析及解决方法优缺点对比

    什么是跨域? 概念:只要协议.域名.端口有任何一个不同,都被当作是不同的域. 复制代码 代码如下: URL                      说明       是否允许通信 http://www.a.com/a.js http://www.a.com/b.js 同一域名下 允许 http://www.a.com/lab/a.js http://www.a.com/script/b.js 同一域名下不同文件夹 允许 http://www.a.com:8000/a.js http://www

  • 动态创建script在IE中缓存js文件时导致编码的解决方法

    先看下重现代码 1, gb2312.html 该文件编码为gb2312 复制代码 代码如下: <!DOCTYPE html> <html> <head> <title></title> <meta charset="gb2312"/> <style> p { color: red; } </style> </head> <body> <button onclic

  • JS超出精度数字问题的解决方法

    精度问题最通俗易懂的解释 比如一个数 1÷3=0.33333333...... 大家都知道3会一直无限循环,数学可以表示,但是计算机要存储,方便下次取出来再使用,但0.333333...... 这个数 无限循环,你让计算机怎么存储?计算机再大的内存它也存不下,对吧! 所以不能存储一个相对于数学来说的值,只能存储一个近似值,所以当计算机存储后再取出来用时就会出现精度问题. JS超出精度数字解决 一.js 最大安全数字是 Math.pow(2,53) - 1,超出这个数字相加会出现精度丢失问题,可通

随机推荐