73

Why does adding </script> in a comment break the parser? Is this a bug or is there something in the documentation I've overlooked?

I've tested this in Chrome, Firefox, Opera, Internet Explorer and they all produce the same result.

Single-line comment:

function Foo(){
  // </script>
  alert("bar");
};

Foo();

Multi-line comment:

function Foo(){
  /*
      </script>
  */
  alert("bar");
};

Foo();
Bjørn-Roger Kringsjå
  • 9,849
  • 6
  • 36
  • 64
  • 23
    The html parse doesn't know anything about the language and the syntax of the script that is written between the `` is the only indication for the parser that the script ended. – t.niese Sep 30 '15 at 07:32
  • 9
    http://stackoverflow.com/questions/236073/why-split-the-script-tag-when-writing-it-with-document-write – JJJ Sep 30 '15 at 07:33
  • 9
    @t.niese has it on the head; ` – Qix - MONICA WAS MISTREATED Sep 30 '15 at 07:46
  • @t.niese That makes sense. I guess my first mistake was to believe that the html parser would hand over the job to an appropriate scripting parser, in this particular case a javascript parser. – Bjørn-Roger Kringsjå Sep 30 '15 at 09:30
  • Any serious use of scripts in HTML should be minified anyway, especially if not a separate resource. IOW, this shouldn't affect production code. – MSalters Sep 30 '15 at 14:05
  • 3
    It *does* hand over the script to an appropriate parser, how do you think your JavaScript gets executed? But, how does the HTML parser know where the script begins and where it ends, i.e. which part to hand off to the scripting parser? Well, it begins with ``. – Jörg W Mittag Sep 30 '15 at 16:38
  • You'll get similar results if you do this: `*/ `. Seems like this issue could have been avoided if everything recognized HTML comment syntax. On a related note, it's too bad the HTML parser doesn't also look for script start tags while it's looking for script end tags. Then things like [this](http://stackoverflow.com/q/32569470/2759272) would be possible. – DoctorDestructo Sep 30 '15 at 23:38

4 Answers4

102

This happens because HTML parser as defined by W3C is totally separated from the JavaScript parser. After the <script> tag it looks for the closing </script>, regardless that it's inside comments or strings, because it treats JS code as normal text.

mck89
  • 18,918
  • 16
  • 89
  • 106
  • 33
    To add, it would be very bad if it worked any other way. Browsers that don't support JavaScript still need to be able to find the closing `` without knowing the parsing rules of the language. And while browsers that don't support JavaScript may be uncommon (although they do exist, even current ones), the same argument can be made for *any* language that has *ever* been supported in *any* browser. Would Firefox need to know the VBScript parsing rules if the page contains a script that's designed to only work on IE? –  Sep 30 '15 at 14:49
33

The HTML parser does not parse JavaScript. It only parses HTML elements, denotated by <tag> and </tag> tags. It has no idea that something is a JavaScript comment. When it sees the </script> closing tag, it assumes the script element is being closed. The same would occur in whatever context the string </script> appeared; for instance, console.log("</script>") would yield the same behavior.

This is a pretty good reason not to embed scripts inside HTML, but rather to include them externally.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • 2
    Note that if you actually want to log the string literal `` in your JavaScript code, you can write `console.log("<\/script>")`. – dan04 Sep 30 '15 at 23:48
11

You can HTML-escape embedded JavaScript code

<script type="text/javascript">
<!--

function Foo(){
 // </script>
  alert("bar");
};

Foo();

//-->
</script>

Thus, the whole JavaScript code is treated as HTML comment by HTML parser and HTML comment lines are ignored by JavaScript interpreter.

Álvaro González
  • 142,137
  • 41
  • 261
  • 360
Shanavas M
  • 1,581
  • 1
  • 17
  • 24
  • 16
    I disagree. This was good practice a decade or two ago, before HTML parsers started to treat the content of ``, **or** you're dealing with XHTML, in which case you're better off wrapping the script in a real CDATA. –  Sep 30 '15 at 08:59
  • @torazaburo thanks, updated the answer – Shanavas M Sep 30 '15 at 11:46
  • 2
    The historical reason for this was actually that some early browsers (Mosaic, Netscape 1, etc.) didn't recognize the ` – Stan Rogers Oct 01 '15 at 02:46
  • This might provide an *alternative* but doesn't answer the actual question of *why* the `` tag is obeyed by the browser. – Josh Oct 01 '15 at 03:54
0

An easier workaround would be embedding comments:

function Foo(){
  //<!-- </script> -->
  alert("bar");
};

Foo();

It will comment the line for javascript AND for html.

Adriano
  • 3,788
  • 5
  • 32
  • 53