Escaping </Script> Tag Inside JavaScript

How to include an escapedscript /script tag in a JavaScript variable?

The issue is that when the browser encounters the closing </script> tag inside a open <script> tag, regardless of the context in which it is used, it will terminate the script tag there. There are a couple of way to avoid this.

Option 1 - Escape the / in the closing script tag:

var script = '<script async src="//somesite.com/feed/livetrend.js"><\/script>';

Option 2 - Wrap the JavaScript in commented out HTML comments:

<script>
/*<!--*/
var script = '<script async src="//somesite.com/feed/livetrend.js"></script>';
/*-->*/
</script>

Using <![CDATA[ and ]]> instead of <!-- and --> also works.

One potential downside to this might be if you also want to have JavaScript strings that also contain these closing comments or CDATA, then it may not work.

Option 3 - Put the JavaScript into an external file:

Of course, moving the JavaScript into an external file will avoid this issue altogether, though it might not be preferable.

Programatically escape / script closing tag in javascript

It does not work as you think.

The first fragment of code does not work because the browser finds the </script> piece in the string and thinks that it is the closing tag of the script element. It treats the rest of the script and the real </script> closing tag as regular text and displays it in the page (except for the </script> tag).

This means that only a fragment of your script is parsed, the parser finds a syntax error in it (the string is not closed) and the script does not run.

There is no way to fix this using JavaScript code. It is not a coding problem. It is an HTML problem (kind of) and its only solution is to write the HTML in a way that avoids the issue.

The HTML document contains a closing tag </script> inside the body of a script element. For normal HTML content (a paragraph, for example) the solution is straight forward: use < and > to encode < and >:

<p> This is a paragraph that contains a <p> closing tag</p>

Escape / in script tag contents

In HTML, as opposite to XHTML, the content of a script element is processed as plain text except for the occurrence of an end tag, so that </ ends processing and must, in conforming documents, start the end tag </script>. There is no general mechanism to avoid this. Any methods that circumvent this feature are unavoidably dependent on the “language” used inside the element. The word “language” is in quotes here, because the content can be just about anything, as long as your code can parse and process it.

So: no general mechanism, but for content other than JavaScript or some of the few other client-side scripting languages recognized by some browsers, you can make your own rules.

How do I properly escape inline Javascript in a script tag?

This is a work in progress, let me know if I've missed a corner case!

The answer is different depending on whether you're using XHTML or HTML.

1. XHTML with Content-Type: application/xhtml+xml header

In this case, you can simply XML escape any entities, turning this file:

console.log("Example Javascript file");
console.log(1</script>2/);
console.log("That previous line prints false");

To this:

<script>
console.log("Example Javascript file");
console.log(1</script>2/);
console.log("That previous line prints false");
</script>

Note that if you're using XHTML with a different Content-Type header, then different browsers may behave differently, and I haven't researched it, so I would recommend fixing the Content-Type header.

2. HTML

Unfortunately, I know of no way to escape it properly in this case (without at least parsing the Javascript). Replacing all instances of / with \/ would cause some Javascript to break, including the previous example.

The best that I can recommend is that you search for </script case-insensitively and throw an exception if you find it. If you're only dealing with string literals or JSON, substitute all instances of / with \/.

Some Javascript minifiers might deal with </script in a safe manner perhaps, let me know if you find one.

Escape single quotes inside script tag php

Try this:

<?php echo  "<script type='text/javascript'>
(function(d){
var url='http://myurl.com';
var iframe = d.createElement('iframe');
(iframe.frameElement || iframe).style.cssText = 'width: 0; height: 0;border: 0;';
iframe.src = 'javascript:false';
d.body.appendChild(iframe);
var doc = iframe.contentWindow.document;
doc.open().write('<body onload=\"window.location.href=\''+url+'\'\">');
doc.close();
})(document);
</script>";
?>

The main error is in the way that you're scaping the single quote.

Because you're trying to get the href value you need to scape first and concatenate, is easier if you use double quote to manage the strings inside PHP. In this way the onload function can be load using \" , and for get the url value just do \' inside the main string.

Also don't worry if you split the Javascript in more lines, that will be do easier identify the errors.

/script within a JavaScript string in a script tag

The HTML parses it as:

<script type="text/javascript">
alert("hello
</script>
");
</script>

With the first occurrence of </script> closing the open <script> element. The common way of avoiding this issue is by including a \ before the / character in the string:

<script type="text/javascript">
alert("hello <\/script>");
</script>

This works because the \ escape character will prevent the browser from recognizing <\/script> as an end tag. Normally \ is used as an escape sequence in JavaScript strings, but as there's no \/ sequence, the escape character is ignored and the string evaluates as '</script'>.

This issue can generally be avoided if you follow the good practice of keeping all of your javascript in external .js files. That said, it's common to see this sort of escaping used for local script fallbacks for unresponsive CDNs.

Script tag in JavaScript string

What happens?

The browser HTML parser will see the </script> within the string and it will interpret it as the end of the script element.

Look at the syntax coloring of this example:

<script>
var test = 'foo... </script> bar.....';
</script>

Note that the word bar is being treated as text content outside of the script element...

A commonly used technique is to use the concatenation operator:

var test = '...... </scr'+'ipt>......';

Escaping /script tag inside javascript

Inside a <script> block it is syntactically illegal to have any </ followed by a name—not just </script>—so you need to escape that anywhere it may appear. For example:

:javascript
var foo = { store: #{@store.to_json.gsub('</','<\/')} };

This will create the sequence <\/ inside your JS strings, which is interpreted to be the same as </. Ensure that you use single quotes in your gsub replacement string, or else use gsub( "</", "<\\/" ) due to the difference between single and double quotes in Ruby.

Shown in action:

irb:02.0> s = "<b>foo</b>" # Here's a dangerous string
#=> "<b>foo</b>"

irb:03.0> a = [s] # Wrapped in an array, for fun.
#=> ["<b>foo</b>"]

irb:04.0> json = a.to_json.gsub( '</', '<\/' ) # Sanitized
irb:05.0> puts json # This is what would come out in your HTML; safe!
#=> ["<b>foo<\/b>"]

irb:06.0> puts JSON.parse(json).first # Same as the original? Yes! Yay!
#=> <b>foo</b>

If you are using Rails (or ActiveSupport) you can enable JSON escaping:

ActiveSupport::JSON::Encoding.escape_html_entities_in_json = true

Seen in action:

irb:02.0> a = ["<b>foo</b>"]
irb:03.0> puts a.to_json # Without the magic
#=> ["<b>foo</b>"]

irb:04.0> require 'active_support'
irb:05.0> ActiveSupport::JSON::Encoding.escape_html_entities_in_json = true
irb:06.0> puts a.to_json # With the magic
#=> ["\u003Cb\u003Efoo\u003C/b\u003E"]

It produces JSON that is more verbose than you need to solve this particular problem, but it is effective.

How to get Jackson to escape a /script in output string?

Ravis answer is wrong. See my comment there.

A better way is to escape the slash in </ with a backslash, like:

<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
...
<script>SomeLib.load(${fn:replace(jsonString, "</", "<\\/")});</script>

Note: two backslashes are needed so the first one is escaped in the JSP syntax.

The good part is, it needs no special decoding.

PS: To do it on Jackson side, see this blog - it covers escaping other characters, but just add slash to the list to escape (all) slash characters.



Related Topics



Leave a reply



Submit