Search code examples
htmlbrowserattributestags

Why does the browser automatically unescape html tag attribute values?


Below I have an HTML tag, and use JavaScript to extract the value of the widget attribute. This code will alert <test> instead of &lt;test&gt;, so the browser automatically unescapes attribute values:

alert(document.getElementById("hau").attributes[1].value)
<div id="hau" widget="&lt;test&gt;"></div>

My questions are:

  1. Can this behavior be prevented in any way, besides doing a double escape of the attribute contents? (It would look like this: &amp;lt;test&amp;gt;)
  2. Does anyone know why the browser behaves like this? Is there any place in the HTML specs that this behavior is mentioned explicitly?

Solution

  • 1) It can be done without doing a double escape

    Looks like yours is closer to htmlEncode(). If you don't mind using jQuery

    alert(htmlEncode($('#hau').attr('widget')))
    
    function htmlEncode(value){
      //create a in-memory div, set it's inner text(which jQuery automatically encodes)
      //then grab the encoded contents back out.  The div never exists on the page.
      return $('<div/>').text(value).html();
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div id="hau" widget="&lt;test&gt;"></div>

    If you're interested in a pure vanilla js solution

    alert(htmlEncode(document.getElementById("hau").attributes[1].value))
    function htmlEncode( html ) {
        return document.createElement( 'a' ).appendChild( 
            document.createTextNode( html ) ).parentNode.innerHTML;
    };
    <div id="hau" widget="&lt;test&gt;"></div>

    2) Why does the browser behave like this?

    Only because of this behaviour, we are able to do a few specific things, such as including quotes inside of a pre-filled input field as shown below, which would not have been possible if the only way to insert " is by adding itself which again would require escaping with another char like \

    <input type='text' value="&quot;You &apos;should&apos; see the double quotes here&quot;" />