The //<![CDATA[
hack is used in XHTML pages that have to parse as both HTML and XML.
In the HTML parsing rules, <script>
and <style>
are special “CDATA elements”, whose contents up to the next </
sequence (HTML4) or </script
sequence (HTML5) are raw data, so if (x<y)
can be written without any encoding; this would foul up XML parsers.
In the XML parsing rules there are no special elements and so the same statement would have to be written as if (x<y)
; this would foul up HTML parsers.
In order to allow <
to be written unescaped and mean the same thing to both XML and HTML parsers, you can wrap the script in an XML CDATA Section, then protect HTML parsers from that odd construct by hiding it in a JavaScript comment.
If you are using this construct to allow you to include these characters in a string literal without escaping, it's not enough, because you still have to escape away both the sequence </
(for HTML) and ]]>
(for XML). One way of escaping those sequences in a JS string literal is to always encode <>&
characters to \x3C
, \x3E
and \x26
respectively... in which case you would no longer need the CDATA Section.
I run the objects through a standard JSON stringifier which follows all the rules, then I replace </script
with <\/script
, not case sensitive. Is this sufficient?
Not necessarily.
HTML syntax. <\/script
is fine for HTML but not XHTML, as above.
JavaScript syntax. There are—due to an unfortunate oversight in the design of JSON—some Unicode control characters that are valid in JSON but not valid in JavaScript.
Most notably the characters U+2028 and U+2029, Line and Paragraph Separator, which act as newlines. Injecting a newline into the middle of a string literal will most likely cause a syntax error (unterminated string literal).
There are more control characters that are supposed to be invalid in JS string literals, but which don't actually break browsers in practice.
If your JSON encoder habitually encodes all non-ASCII characters this won't be a problem.
Alternative to getting embedded JS-encoding right: avoid inline scripts completely, put your data in the HTML page (where normal HTML-escaping rules apply) and retrieve it from linked scripts using DOM methods.