javascripthtmldecodeuricomponent

HTML does not show decoded %3C?


Following blocks of code are similar but have different input strings and hence different results:

// This does not change HTML
var str = "%3Cdiv%3E"; // <div>
var str_dec = decodeURIComponent(str);
console.log(str_dec); // Console output is `<div>`
document.getElementById("p1").innerHTML = "1: " + str_dec; // No HTML output

// This works fine within HTML
var str = "%3C0%3E"; // <0>
var str_dec = decodeURIComponent(str);
console.log(str_dec); // Console output is `<0>`
document.getElementById("p2").innerHTML = "2: " + str_dec; // HTML output is `<0>`
<p id="p1"></p>
<p id="p2"></p>

Although, console shows that decoding works fine in first case, why it does not appear in the HTML?


Solution

  • This is because <0> is not a valid HTML tag, as SGML (the language which HTML used to be derived from) tags cannot begin with a digit:

    The element name immediately follows the tag open delimiter. An element name consist of a letter followed by up to 72 letters, digits, periods, or hyphens. Names are not case sensitive.

    https://www.w3.org/MarkUp/html3/HTMLandSGML.html

    Since the code is assigning the innerHTML property of an Element, the browser tries to parse the value as HTML and isn't treating <0> as an HTML element, instead opting to treat it as a text value; whereas <div> is a valid HTML element, so the browser treats it as such.

    If you inspect the output in the console, you'll actually see an empty <div> DOM node inside the paragraph p1 (and the string <0> in p2):

    enter image description here

    If you don't want the browser to parse the assigned value as HTML, use the safer, simpler textContent property instead.