innerHTML Application

innerHTML Application

Blank's blog: http://www.planabc.net/
The use of the innerHTML property is very popular because it provides an easy way to completely replace the contents of an HTML element. Another approach is to use the DOM Level 2 API (removeChild, createElement, appendChild). But it is obvious that using innerHTML to modify the DOM tree is a very easy and effective method. However, you need to be aware that innerHTML has some issues of its own:
    When an HTML string contains a script tag marked as defer (<script defer>…</script>), a script injection attack can occur on Internet Explorer if the innerHTML attribute is not handled properly. Setting innerHTML will destroy existing HTML elements that have event handlers registered, potentially causing memory leaks on some browsers.

There are a few other minor drawbacks that are worth mentioning:
    You can't get references to elements you've just created, you need to manually add code to get those references (using DOM APIs). You cannot set the innerHTML property on all HTML elements in all browsers (for example, Internet Explorer does not allow you to set the innerHTML property on table row elements).

I am more concerned about the security and memory issues associated with using the innerHTML property. Obviously, these are not new problems, and there are already smart people who have figured out ways around some of these issues.
Douglas Crockford wrote a cleanup function that is responsible for breaking some circular references caused by event handlers registered with HTML elements and allowing the garbage collector to free the memory associated with these HTML elements.
Removing script tags from an HTML string is not as easy as it seems. A regular expression may do what you expect, although it is hard to know whether all possibilities are covered. Here is my solution:
/<script[^>]*>[\S\s]*?<\/script[^>]*>/ig
Now, let's combine these two techniques into a single setInnerHTML function and bind the setInnerHTML function to YUI's YAHOO.util.Dom:
YAHOO.util.Dom.setInnerHTML = function (el, html) {
el = YAHOO.util.Dom.get(el);
if (!el || typeof html !== 'string') {
return null;
}
// Break the circular reference
(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];
// Clear child nodes
arguments.callee(c);
// Remove all listeners registered on the element through YUI's addListener
YAHOO.util.Event.purgeElement(c);
}
}
})(el);
// Remove the script from the HTML string and set the innerHTML property
el.innerHTML = html.replace(/<script[^>]*>[\S\s]*?<\/script[^>]*>/ig, "");
// Return a reference to the first child node
return el.firstChild;
};
If there is anything else this function should have or if I'm missing something in the regex, please let me know.
Obviously, there are many other ways to inject malicious code on a web page. The setInnerHTML function normalizes the execution behavior of <script> tags on all A-grade browsers only. If you plan to inject untrusted HTML code, make sure to filter it on the server first. There are many libraries that can do this.
Original article: The Problem With innerHTML by Julien Lecomte

<<:  How MySQL handles implicit default values

>>:  Dockerfile implementation code when starting two processes in a docker container

Recommend

Small problem with the spacing between label and input in Google Browser

Code first, then text Copy code The code is as fol...

Analysis of MySQL's method of exporting to Excel

This article describes how to use MySQL to export...

A brief discussion on Flex layout and scaling calculation

1. Introduction to Flex Layout Flex is the abbrev...

5 ways to achieve the diagonal header effect in the table

Everyone must be familiar with table. We often en...

About Zabbix forget admin login password reset password

The problem of resetting the password for Zabbix ...

How to quickly insert 10 million records into MySQL

I heard that there is an interview question: How ...

Vue implements time countdown function

This article example shares the specific code of ...

Linux command line operation Baidu cloud upload and download files

Table of contents 0. Background 1. Installation 2...

Example code for implementing ellipse trajectory rotation using CSS3

Recently, the following effects need to be achiev...

Several ways to implement CSS height changing with width ratio

[Solution 1: padding implementation] principle: I...

Vue implements tree table through element tree control

Table of contents Implementation effect diagram I...

jQuery achieves breathing carousel effect

This article shares the specific code of jQuery t...