Can I escape html special chars in javascript?

I want to display a text to HTML by a javascript function. How can I escape html special chars in JS? Is there an API ?

Answers:

Answer
function escapeHtml(unsafe) {
    return unsafe
         .replace(/&/g, "&")
         .replace(/</g, "&lt;")
         .replace(/>/g, "&gt;")
         .replace(/"/g, "&quot;")
         .replace(/'/g, "&#039;");
 }
Answer

function escapeHtml(html){
  var text = document.createTextNode(html);
  var p = document.createElement('p');
  p.appendChild(text);
  return p.innerHTML;
}

// Escape while typing & print result
document.querySelector('input').addEventListener('input', e => {
  console.clear();
  console.log( escapeHtml(e.target.value) );
});
<input style='width:90%; padding:6px;' placeholder='&lt;b&gt;cool&lt;/b&gt;'>

Answer

You can use jQuery's .text() function.

For example:

http://jsfiddle.net/9H6Ch/

From the jQuery documentation regarding the .text() function:

We need to be aware that this method escapes the string provided as necessary so that it will render correctly in HTML. To do so, it calls the DOM method .createTextNode(), does not interpret the string as HTML.

Previous Versions of the jQuery Documentation worded it this way (emphasis added):

We need to be aware that this method escapes the string provided as necessary so that it will render correctly in HTML. To do so, it calls the DOM method .createTextNode(), which replaces special characters with their HTML entity equivalents (such as &lt; for <).

Answer

I think I found the proper way to do it...

// Create a DOM Text node:
var text_node = document.createTextNode(unescaped_text);

// Get the HTML element where you want to insert the text into:
var elem = document.getElementById('msg_span');

// Optional: clear its old contents
//elem.innerHTML = '';

// Append the text node into it:
elem.appendChild(text_node);
Answer

Using lodash

_.escape('fred, barney, & pebbles');
// => 'fred, barney, &amp; pebbles'

source code

Answer

This is, by far, the fastest way I have seen it done. Plus, it does it all without adding, removing, or changing elements on the page.

function escapeHTML(unsafeText) {
    let div = document.createElement('div');
    div.innerText = unsafeText;
    return div.innerHTML;
}
Answer

It was interesting to find a better solution:

var escapeHTML = function(unsafe) {
  return unsafe.replace(/[&<"']/g, function(m) {
    switch (m) {
      case '&':
        return '&amp;';
      case '<':
        return '&lt;';
      case '"':
        return '&quot;';
      default:
        return '&#039;';
    }
  });
};

I do not parse > because it does not break XML/HTML code in the result.

Here are the benchmarks: http://jsperf.com/regexpairs Also, I created a universal escape function: http://jsperf.com/regexpairs2

Answer

The most concise and performant way to display unencoded text is to use textContent property.

Faster than using innerHTML. And that's without taking into account escaping overhead.

document.body.textContent = 'a <b> c </b>';

Answer

DOM Elements support converting text to HTML by assigning to innerText. innerText is not a function but assigning to it works as if the text were escaped.

document.querySelectorAll('#id')[0].innerText = 'unsafe " String >><>';
Answer

You can encode every character in your string:

function encode(e){return e.replace(/[^]/g,function(e){return"&#"+e.charCodeAt(0)+";"})}

Or just target the main characters to worry about (&, inebreaks, <, >, " and ') like:

function encode(r){
return r.replace(/[\x26\x0A\<>'"]/g,function(r){return"&#"+r.charCodeAt(0)+";"})
}

test.value=encode('How to encode\nonly html tags &<>\'" nice & fast!');

/*************
* \x26 is &ampersand (it has to be first),
* \x0A is newline,
*************/
<textarea id=test rows="9" cols="55">&#119;&#119;&#119;&#46;&#87;&#72;&#65;&#75;&#46;&#99;&#111;&#109;</textarea>

Answer

Came across this issue when building a DOM structure. This question helped me solve it. I wanted to use a double chevron as a path separator, but appending a new text node directly resulted in the escaped character code showing, rather than the character itself:

var _div = document.createElement('div');
var _separator = document.createTextNode('&raquo;');
//_div.appendChild(_separator); /* this resulted in '&raquo;' being displayed */
_div.innerHTML = _separator.textContent; /* this was key */
Answer

A one-liner (for ES6+):

var escapeHtml = s => (s + '').replace(/[&<>"']/g, m => ({
    '&': '&amp;', '<': '&lt;', '>': '&gt;',
    '"': '&quot;', "'": '&#39;'
})[m]);

For older versions:

function escapeHtml(s) {
    return (s + '').replace(/[&<>"']/g, function (m) {
        return ({
            '&': '&amp;', '<': '&lt;', '>': '&gt;',
            '"': '&quot;', "'": '&#39;'
        })[m];
    });
}
Answer

Try this, using the prototype.js library:

string.escapeHTML();

Try a demo

Answer

I came up with this solution.

Let's assume that we want to add some html to the element with unsafe data from the user or database.

var unsafe = 'some unsafe data like <script>alert("oops");</script> here';

var html = '';
html += '<div>';
html += '<p>' + unsafe + '</p>';
html += '</div>';

element.html(html);

It's unsafe against XSS attacks. Now add this.

$(document.createElement('div')).html(unsafe).text();

So it is

var unsafe = 'some unsafe data like <script>alert("oops");</script> here';

var html = '';
html += '<div>';
html += '<p>' + $(document.createElement('div')).html(unsafe).text(); + '</p>';
html += '</div>';

element.html(html);

To me this is much easier than using .replace() and it'll remove!!! all possible html tags (I hope).

Answer

If you already use modules in your app, you can use escape-html module.

import escapeHtml from 'escape-html';
const unsafeString = '<script>alert("XSS");</script>';
const safeString = escapeHtml(unsafeString);

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.