[javascript] How to decode HTML entities using jQuery?

How do I use jQuery to decode HTML entities in a string?

This question is related to javascript jquery html

The answer is


You can use the he library, available from https://github.com/mathiasbynens/he

Example:

console.log(he.decode("Jörg &amp Jürgen rocked to & fro "));
// Logs "Jörg & Jürgen rocked to & fro"

I challenged the library's author on the question of whether there was any reason to use this library in clientside code in favour of the <textarea> hack provided in other answers here and elsewhere. He provided a few possible justifications:

  • If you're using node.js serverside, using a library for HTML encoding/decoding gives you a single solution that works both clientside and serverside.

  • Some browsers' entity decoding algorithms have bugs or are missing support for some named character references. For example, Internet Explorer will both decode and render non-breaking spaces (&nbsp;) correctly but report them as ordinary spaces instead of non-breaking ones via a DOM element's innerText property, breaking the <textarea> hack (albeit only in a minor way). Additionally, IE 8 and 9 simply don't support any of the new named character references added in HTML 5. The author of he also hosts a test of named character reference support at http://mathias.html5.org/tests/html/named-character-references/. In IE 8, it reports over one thousand errors.

    If you want to be insulated from browser bugs related to entity decoding and/or be able to handle the full range of named character references, you can't get away with the <textarea> hack; you'll need a library like he.

  • He just darn well feels like doing things this way is less hacky.


I just had to have an HTML entity charater (⇓) as a value for a HTML button. The HTML code looks good from the beginning in the browser:

<input type="button" value="Embed & Share  &dArr;" id="share_button" />

Now I was adding a toggle that should also display the charater. This is my solution

$("#share_button").toggle(
    function(){
        $("#share").slideDown();
        $(this).attr("value", "Embed & Share " + $("<div>").html("&uArr;").text());
    }

This displays ⇓ again in the button. I hope this might help someone.


Use

myString = myString.replace( /\&amp;/g, '&' );

It is easiest to do it on the server side because apparently JavaScript has no native library for handling entities, nor did I find any near the top of search results for the various frameworks that extend JavaScript.

Search for "JavaScript HTML entities", and you might find a few libraries for just that purpose, but they'll probably all be built around the above logic - replace, entity by entity.


To decode HTML Entities with jQuery, just use this function:

function html_entity_decode(txt){
    var randomID = Math.floor((Math.random()*100000)+1);
    $('body').append('<div id="random'+randomID+'"></div>');
    $('#random'+randomID).html(txt);
    var entity_decoded = $('#random'+randomID).html();
    $('#random'+randomID).remove();
    return entity_decoded;
}

How to use:

Javascript:

var txtEncoded = "&aacute; &eacute; &iacute; &oacute; &uacute;";
$('#some-id').val(html_entity_decode(txtEncoded));

HTML:

<input id="some-id" type="text" />

Without any jQuery:

_x000D_
_x000D_
function decodeEntities(encodedString) {_x000D_
  var textArea = document.createElement('textarea');_x000D_
  textArea.innerHTML = encodedString;_x000D_
  return textArea.value;_x000D_
}_x000D_
_x000D_
console.log(decodeEntities('1 &amp; 2')); // '1 & 2'
_x000D_
_x000D_
_x000D_

This works similarly to the accepted answer, but is safe to use with untrusted user input.


Security issues in similar approaches

As noted by Mike Samuel, doing this with a <div> instead of a <textarea> with untrusted user input is an XSS vulnerability, even if the <div> is never added to the DOM:

_x000D_
_x000D_
function decodeEntities(encodedString) {_x000D_
  var div = document.createElement('div');_x000D_
  div.innerHTML = encodedString;_x000D_
  return div.textContent;_x000D_
}_x000D_
_x000D_
// Shows an alert_x000D_
decodeEntities('<img src="nonexistent_image" onerror="alert(1337)">')
_x000D_
_x000D_
_x000D_

However, this attack is not possible against a <textarea> because there are no HTML elements that are permitted content of a <textarea>. Consequently, any HTML tags still present in the 'encoded' string will be automatically entity-encoded by the browser.

_x000D_
_x000D_
function decodeEntities(encodedString) {_x000D_
    var textArea = document.createElement('textarea');_x000D_
    textArea.innerHTML = encodedString;_x000D_
    return textArea.value;_x000D_
}_x000D_
_x000D_
// Safe, and returns the correct answer_x000D_
console.log(decodeEntities('<img src="nonexistent_image" onerror="alert(1337)">'))
_x000D_
_x000D_
_x000D_

Warning: Doing this using jQuery's .html() and .val() methods instead of using .innerHTML and .value is also insecure* for some versions of jQuery, even when using a textarea. This is because older versions of jQuery would deliberately and explicitly evaluate scripts contained in the string passed to .html(). Hence code like this shows an alert in jQuery 1.8:

_x000D_
_x000D_
//<!-- CDATA_x000D_
// Shows alert_x000D_
$("<textarea>")_x000D_
.html("<script>alert(1337);</script>")_x000D_
.text();_x000D_
_x000D_
//-->
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.2.3/jquery.min.js"></script>
_x000D_
_x000D_
_x000D_

* Thanks to Eru Penkman for catching this vulnerability.


The easiest way is to set a class selector to your elements an then use following code:

$(function(){
    $('.classSelector').each(function(a, b){
        $(b).html($(b).text());
    });
});

Nothing any more needed!

I had this problem and found this clear solution and it works fine.


I think you're confusing the text and HTML methods. Look at this example, if you use an element's inner HTML as text, you'll get decoded HTML tags (second button). But if you use them as HTML, you'll get the HTML formatted view (first button).

<div id="myDiv">
    here is a <b>HTML</b> content.
</div>
<br />
<input value="Write as HTML" type="button" onclick="javascript:$('#resultDiv').html($('#myDiv').html());" />
&nbsp;&nbsp;
<input value="Write as Text" type="button" onclick="javascript:$('#resultDiv').text($('#myDiv').html());" />
<br /><br />
<div id="resultDiv">
    Results here !
</div>

First button writes : here is a HTML content.

Second button writes : here is a <B>HTML</B> content.

By the way, you can see a plug-in that I found in jQuery plugin - HTML decode and encode that encodes and decodes HTML strings.


Alternatively, theres also a library for it..

here, https://cdnjs.com/libraries/he

npm install he                 //using node.js

<script src="js/he.js"></script>  //or from your javascript directory

The usage is as follows...

//to encode text 
he.encode('© Ande & Nonso® Company LImited 2018');  

//to decode the 
he.decode('&copy; Ande &amp; Nonso&reg; Company Limited 2018');

cheers.


Extend a String class:

String::decode = ->
  $('<textarea />').html(this).text()

and use as method:

"&lt;img src='myimage.jpg'&gt;".decode()

Suppose you have below String.

Our Deluxe cabins are warm, cozy &amp; comfortable

var str = $("p").text(); // get the text from <p> tag
$('p').html(str).text();  // Now,decode html entities in your variable i.e 

str and assign back to

tag.

that's it.


You have to make custom function for html entities:

function htmlEntities(str) {
return String(str).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g,'&gt;').replace(/"/g, '&quot;');
}

encode:

_x000D_
_x000D_
$("<textarea/>").html('<a>').html(); // return '&lt;a&gt'
_x000D_
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<textarea/>
_x000D_
_x000D_
_x000D_

decode:

_x000D_
_x000D_
$("<textarea/>").html('&lt;a&gt').val() // return '<a>'
_x000D_
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<textarea/>
_x000D_
_x000D_
_x000D_


Like Mike Samuel said, don't use jQuery.html().text() to decode html entities as it's unsafe.

Instead, use a template renderer like Mustache.js or decodeEntities from @VyvIT's comment.

Underscore.js utility-belt library comes with escape and unescape methods, but they are not safe for user input:

_.escape(string)

_.unescape(string)


For ExtJS users, if you already have the encoded string, for example when the returned value of a library function is the innerHTML content, consider this ExtJS function:

Ext.util.Format.htmlDecode(innerHtmlContent)

I think that is the exact opposite of the solution chosen.

var decoded = $("<div/>").text(encodedStr).html();

Try this :

_x000D_
_x000D_
var htmlEntities = "&lt;script&gt;alert('hello');&lt;/script&gt;";_x000D_
var htmlDecode =$.parseHTML(htmlEntities)[0]['wholeText'];_x000D_
console.log(htmlDecode);
_x000D_
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
_x000D_
_x000D_
_x000D_

parseHTML is a Function in Jquery library and it will return an array that includes some details about the given String..

in some cases the String is being big, so the function will separate the content to many indexes..

and to get all the indexes data you should go to any index, then access to the index called "wholeText".

I chose index 0 because it's will work in all cases (small String or big string).


Here are still one problem: Escaped string does not look readable when assigned to input value

var string = _.escape("<img src=fake onerror=alert('boo!')>");
$('input').val(string);

Exapmle: https://jsfiddle.net/kjpdwmqa/3/


The question is limited by 'with jQuery' but it might help some to know that the jQuery code given in the best answer here does the following underneath...this works with or without jQuery:

function decodeEntities(input) {
  var y = document.createElement('textarea');
  y.innerHTML = input;
  return y.value;
}

Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to jquery

How to make a variable accessible outside a function? Jquery assiging class to th in a table Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Getting all files in directory with ajax Bootstrap 4 multiselect dropdown Cross-Origin Read Blocking (CORB) bootstrap 4 file input doesn't show the file name Jquery AJAX: No 'Access-Control-Allow-Origin' header is present on the requested resource how to remove json object key and value.?

Examples related to html

Embed ruby within URL : Middleman Blog Please help me convert this script to a simple image slider Generating a list of pages (not posts) without the index file Why there is this "clear" class before footer? Is it possible to change the content HTML5 alert messages? Getting all files in directory with ajax DevTools failed to load SourceMap: Could not load content for chrome-extension How to set width of mat-table column in angular? How to open a link in new tab using angular? ERROR Error: Uncaught (in promise), Cannot match any routes. URL Segment