How do I use jQuery to decode HTML entities in a string?
-
The premature choice of technology (jQuery) invites answers with security issues. This might be better off closed as a duplicate of https://stackoverflow.com/questions/1912501/unescape-html-entities-in-javascript. – Wladimir Palant Feb 26 '20 at 13:34
20 Answers
Security note: using this answer (preserved in its original form below) may introduce an XSS vulnerability into your application. You should not use this answer. Read lucascaro's answer for an explanation of the vulnerabilities in this answer, and use the approach from either that answer or Mark Amery's answer instead.
Actually, try
var encodedStr = "This is fun & stuff";
var decoded = $("<div/>").html(encodedStr).text();
console.log(decoded);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div/>

- 4,433
- 2
- 26
- 37

- 4,884
- 1
- 16
- 2
-
182Do **not** do this with untrusted input. Many browsers load images and fire related events even if the node is not attached to the DOM. Try running `$("").html('
')`. In Firefox or Safari it fires the alert. – Mike Samuel Mar 16 '11 at 20:37
-
@Mike, so what do you recommend instead? your answer of .replace() is no good if you don't know what you're replacing... – ekkis May 29 '11 at 01:35
-
7@ekkis, you need to strip tags before trying to decode entities. `str.replace(/<\/?\w(?:[^"'>]|"[^"]*"|'[^']*')*>/g, "")` or something similar. – Mike Samuel May 29 '11 at 05:07
-
2A better implementation (in my opinion) that strips most HTML tags (courtesy of Mike) from the input is in my answer of a [similar question](http://stackoverflow.com/a/9609450/24950). It also does not have the overhead of jQuery so it's quite suitable to other environments. – Robert K Mar 07 '12 at 21:41
-
6@MichaelStum your edit here invalidated both Mike Samuel's comment and the next-highest-voted answer, and did so *without actually fixing the XSS vulnerability* for all jQuery versions (as explained in the answer below). Adding a security warning to this answer would be reasonable (and I'm going to do so); rendering other discussion on this page nonsensical while failing to actually fix the security hole definitely isn't! – Mark Amery Dec 28 '16 at 16:08
-
I used your code for wordpress API with html entity handling `$($.parseHTML(item.title.rendered)).text(),` – Pranesh Janarthanan May 18 '21 at 11:15
Without any jQuery:
function decodeEntities(encodedString) {
var textArea = document.createElement('textarea');
textArea.innerHTML = encodedString;
return textArea.value;
}
console.log(decodeEntities('1 & 2')); // '1 & 2'
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:
function decodeEntities(encodedString) {
var div = document.createElement('div');
div.innerHTML = encodedString;
return div.textContent;
}
// Shows an alert
decodeEntities('<img src="nonexistent_image" onerror="alert(1337)">')
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.
function decodeEntities(encodedString) {
var textArea = document.createElement('textarea');
textArea.innerHTML = encodedString;
return textArea.value;
}
// Safe, and returns the correct answer
console.log(decodeEntities('<img src="nonexistent_image" onerror="alert(1337)">'))
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 atextarea
. 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:
//<!-- CDATA
// Shows alert
$("<textarea>")
.html("<script>alert(1337);</script>")
.text();
//-->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.2.3/jquery.min.js"></script>
* Thanks to Eru Penkman for catching this vulnerability.

- 16,550
- 4
- 37
- 47
-
6It might be a good idea to destroy the textarea after extracting its value: `decodedString = textArea.value;` `textArea.remove();` `return decodedString;` – Werner Feb 26 '16 at 07:05
-
2Or only if the version of javascript actually supports remove(): `if ('remove' in Element.prototype) textArea.remove();` – Werner Feb 26 '16 at 07:34
-
7@Werner As soon as the function has exited, there will be no more variables holding a reference to it so it will be automatically removed by the [garbage collector](https://developer.mozilla.org/docs/Web/JavaScript/Memory_Management). – user2428118 Jan 12 '17 at 14:15
-
I'm using this in combination with .NET from code-behind of a button click, and for some reason the accepted answer caused a postback. This answer did not, so this is the best answer for me. Thanks! – Snailer Jul 14 '17 at 09:53
-
@Snailer `$("").html(string).text()` **will execute any javascript in the string provided**, which I suspect is what was causing your problem. The accepted answer should be updated to this one. – jbowman Jan 08 '18 at 22:34
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:

- 1
- 1

- 3,160
- 1
- 23
- 23
-
2This actually deserves way more upvotes! Definitely my preferred solution. They included `unescape` in the docs by now, btw. – lethal-guitar May 17 '13 at 13:01
-
-
5`_.unescape("'")` results in just "'" instead of a single-quote. Is there something I'm missing or does underscore not escape to HTML entity codes as shown on: http://www.w3schools.com/tags/ref_entities.asp – Jason Axelson Dec 02 '13 at 19:31
-
@JasonAxelson created https://github.com/jashkenas/underscore/issues/1370 for this. – Alan Hamlett Dec 09 '13 at 10:17
-
6The bug on github was closed as "Won't fix"; that means that this solution doesn't work and will not work. – Igor Chubin Dec 29 '13 at 11:03
-
1Do not use _.unescape as well because it's not safe either. This `_.unescape("<img src=fake onerror=alert('boo!')>")` will trigger JS function as well. Try this instead: [decodeEntities](http://stackoverflow.com/a/27385169/175954) – VyvIT Dec 11 '14 at 14:40
-
3You say that Underscore's *"`escape` and `unescape` methods ... are not safe for user input"*. What do you mean by this? It sounds like nonsense to me, but perhaps I'm missing something - can you clarify? – Mark Amery Jul 10 '15 at 20:03
-
2@VyvIT Tried `_.unescape("<img src=fake onerror=alert('boo!')>")` (in Chrome / FF/ IE). But it *did not* show up any alert. Tried it in console as well as put it in my JS file too. Same result. – Vivek Athalye Mar 05 '17 at 13:58
-
+1, unless you _really_ need to lower your overhead and _not_ use a library. If there's any way you can, you should. [Lodash](https://lodash.com/docs/latest) has the same `_.unescape()` and many other similar libraries do as well. – Stephan Samuel Jul 30 '19 at 18:40
-
Underscore.js methods `escape` and `unescape` ARE safe. If you look at [code](https://github.com/jashkenas/underscore/blob/master/underscore.js#L1467) of these methods you can see that it has map (dictionary) of escaped and unescaped HTML entities which is used for escaping and unescaping. The problem is that it works ONLY for 5 characters (entities). – ands Oct 24 '19 at 18:02
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());" />
<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.

- 30,738
- 21
- 105
- 131

- 47,715
- 17
- 91
- 122
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;
}

- 3,458
- 28
- 26
encode:
$("<textarea/>").html('<a>').html(); // return '<a>'
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<textarea/>
decode:
$("<textarea/>").html('<a>').val() // return '<a>'
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<textarea/>

- 4,433
- 2
- 26
- 37

- 247
- 2
- 2
-
4there's already an answer that works, and it's almost identical to this. We don't need duplicate answers – markasoftware Sep 21 '14 at 21:48
-
5This is the valid answer. tom's answer uses a DIV element, which makes that answer vulnerable to XSS. – hodgef Mar 23 '16 at 19:39
-
3
-
are you sure that it works? I mean probably is my browser but it's kind of weird what happens on the text area – Ruslan López Dec 02 '20 at 20:30
-
You can use the he library, available from https://github.com/mathiasbynens/he
Example:
console.log(he.decode("Jörg & 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 (
) correctly but report them as ordinary spaces instead of non-breaking ones via a DOM element'sinnerText
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.

- 1
- 1

- 143,130
- 81
- 406
- 459
-
5+1 jQuery is not the solution to everything. Use the right tool for the job. – Mathias Bynens May 11 '14 at 19:56
-
These is the best way to decode HTML entities. All other answers (on this and similar questions) either use innerHTML (create new HTML element, process HTML code and then obtain innerHTML of that element, this can be vulnerable to XSS attacks if you are not VERY careful, [see more](https://stackoverflow.com/a/1395954)), or they suggest using Underscore.js [unescape](https://underscorejs.org/#unescape) or Lodash [unescape](https://lodash.com/docs/#unescape) methods which are both incomplete (works only for few HTML entities). The he library is most complete and safe option! – ands Oct 24 '19 at 20:17
Try this :
var htmlEntities = "<script>alert('hello');</script>";
var htmlDecode =$.parseHTML(htmlEntities)[0]['wholeText'];
console.log(htmlDecode);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
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).

- 64
- 4
-
While this code snippet may be the solution, [including an explanation](//meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers) really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. – Johan Mar 26 '19 at 11:45
-
-
Use
myString = myString.replace( /\&/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.

- 30,738
- 21
- 105
- 131
You have to make custom function for html entities:
function htmlEntities(str) {
return String(str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g,'>').replace(/"/g, '"');
}

- 752
- 6
- 18
-
-
-
Original question was how to _**decode**_ entities — this does the _opposite_ of what is desired; it _**encodes**_ an extremely limited set of characters _into_ entities. As the down-vote tooltip says, "This answer is not useful". I'm surprised that after 4 years it still has a net-positive score. – Stephen P Jan 11 '17 at 01:40
Suppose you have below String.
Our Deluxe cabins are warm, cozy & 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.

- 14,888
- 21
- 101
- 165

- 1,418
- 12
- 6
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)
-
This will only work for 5 HTML entities. You can see this in [documentation](https://docs.sencha.com/extjs/6.2.0/modern/Ext.String.html#method-htmlDecode) and [source code](https://docs.sencha.com/extjs/6.2.0/modern/src/String.js.html#Ext.String-method-htmlDecode). – ands Oct 24 '19 at 18:27
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 ⇓" 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("⇑").text());
}
This displays ⇓ again in the button. I hope this might help someone.

- 30,738
- 21
- 105
- 131

- 4,133
- 1
- 36
- 35
-
Simpler would be to use a unicode escape sequence (i.e. `"Embed & Share \u21d1"`), or better yet just `"Embed & Share ⇑"` if you're able to serve your script in UTF-8 (or UTF-16, or any other encoding that supports the ⇑ character). Using a DOM element to parse a HTML entity just to bake an arbitrary unicode character into a JavaScript string is a cunning and creative approach that would make Rube Goldberg proud, but isn't good practice; unicode escapes are in the language specifically to handle this use case. – Mark Amery May 11 '14 at 19:53
Extend a String class:
String::decode = ->
$('<textarea />').html(this).text()
and use as method:
"<img src='myimage.jpg'>".decode()

- 26,306
- 36
- 159
- 225

- 2,478
- 25
- 24
You don't need jQuery to solve this problem, as it creates a bit of overhead and dependency.
I know there are a lot of good answers here, but since I have implemented a bit different approach, I thought to share.
This code is a perfectly safe security-wise approach, as the escaping handler depends on the browser, instead on the function. So, if some vulnerability will be discovered in the future, this solution is covered.
const decodeHTMLEntities = text => {
// Create a new element or use one from cache, to save some element creation overhead
const el = decodeHTMLEntities.__cache_data_element
= decodeHTMLEntities.__cache_data_element
|| document.createElement('div');
const enc = text
// Prevent any mixup of existing pattern in text
.replace(/⪪/g, '⪪#')
// Encode entities in special format. This will prevent native element encoder to replace any amp characters
.replace(/&([a-z1-8]{2,31}|#x[0-9a-f]+|#\d+);/gi, '⪪$1⪫');
// Encode any HTML tags in the text to prevent script injection
el.textContent = enc;
// Decode entities from special format, back to their original HTML entities format
el.innerHTML = el.innerHTML
.replace(/⪪([a-z1-8]{2,31}|#x[0-9a-f]+|#\d+)⪫/gi, '&$1;')
.replace(/⪪#/g, '⪪');
// Get the decoded HTML entities
const dec = el.textContent;
// Clear the element content, in order to preserve a bit of memory (in case the text is big)
el.textContent = '';
return dec;
}
// Example
console.log(decodeHTMLEntities("<script>alert('∳∳∳∳⪪#x02233⪫');</script>"));
// Prints: <script>alert('∳∳∳∳⪪#x02233⪫');</script>
By the way, I have chosen to use the characters ⪪
and ⪫
, because they are rarely used, so the chance of impacting the performance by matching them is significantly lower.

- 9,712
- 3
- 47
- 48
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/

- 819
- 1
- 12
- 14
-
This is not an answer to the question. OP asks to decode (unescape) HTML entity, but in this answer you are using `escape` method of Underscore.js. Also there no explanation how your code sample should solve OP's problem. – ands Oct 24 '19 at 18:42
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('© Ande & Nonso® Company Limited 2018');
cheers.

- 1,163
- 1
- 14
- 35
-
There already is an [answer](https://stackoverflow.com/a/23596964/6476044) about [he library](https://github.com/mathiasbynens/he) which is complete, with simple code example and good explanation why and when should you use [he library](https://github.com/mathiasbynens/he). – ands Oct 24 '19 at 18:39
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 = "á é í ó ú";
$('#some-id').val(html_entity_decode(txtEncoded));
HTML:
<input id="some-id" type="text" />

- 11
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.

- 1,825
- 4
- 29
- 40
-
This is not an answer to OP's question. OP asks to decode HTML entities in STRING, NOT only this does not solve the OP's problem but also it replaces escaped HTML entities in HTML element with unesceped ones which should't be done. – ands Oct 24 '19 at 18:50
I think that is the exact opposite of the solution chosen.
var decoded = $("<div/>").text(encodedStr).html();

- 232,980
- 40
- 330
- 338

- 77
- 8