I've been trying some tricks in javascript and came to a ridiculous problem: I can't use <script> as a substring in a javascript string! Here is an example:
<html>
<head>
<script>
alert("<script></script>");
</script>
</head>
</html>
It supposed to print out <script></script>, but instead, I get this:
");
Printed out on the page, as HTML.
Question: How can I use <script> followed by </script> substrings in Javascript, and why is it acting that way?
Here is JSFiddle of it.
What's tripping you up is the </script>. The HTML parser doesn't recognize Javascript strings or nested <script> tags, so it's interpreting that as the closing tag for the initial <script>. That is, this part of the document is parsed as:
<script> (open tag)
alert("<script> (text node - contents of the script)
</script> (close tag)
"); (text node - plain text)
The second </script> is ignored, as there's no other <script> tag for it to close.
To work around this, break up </script so that the HTML parser doesn't see it. For instance:
alert("<script><\/script>");
or:
alert("<script><" + "/script>");
or just put the code in an external Javascript file. This issue only arises for inline scripts.
it is because of the \ I believe. i have no concrete explanation since I am a newbie to Javascript but this code should work:
alert("<script><\/script>");
came up with it using Java knowledge.. Haha since the \ is an escape key in many languages.
Alert(\<script>\</script>\)
Related
To do something like that for example:
<script> for(var i=0; i<5; i+=1){ </script>
<h1>hello</h1>
<script> } </script>
If we used <%%> instead of <script> in aspx page it would print "hello" five times.
I just thought it would be really awesome if we can!
No. That approach is only used in back-end languages such as ASP and PHP. In those languages, the engine parses the source code for ASP or PHP instructions in order to produce its output.
When dealing with JavaScript in an HTML document (inside <script> tags), it is the HTML document which is first interpreted, and during that parsing, the JavaScript is identified and run. JavaScript does not initially generate HTML and is merely included in it.
I am developing an application that uses loops to create a desired output; here from number 1 to 50. I am using a for loop and uses the concatenation method to show the looped numbers. But then the debugger in the browser is saying that I have written an unbalanced tree.
Here is the error:
An unbalanced tree was written using document.write() causing data from the network to be reparsed. For more information https://developer.mozilla.org/en/Optimizing_Your_Pages_for_Speculative_Parsing
Here is the code:
<script type="text/javascript">
for(i=1;i<=50;i++){
document.write(""+i+"");
}
</script>
Note: The links I am creating use an id attribute to link somewhere exactly on the page.
Thanks for help.
It's a warning. It happens in Firefox 4 and later.
From MDN: Optimizing your pages for speculative parsing:
However, in Firefox 4 and later the HTML parser also runs the HTML tree construction algorithm speculatively. The upside is that when a speculation succeeds, there's no need to reparse the part of the incoming file that was already scanned for scripts, style sheets and images. The downside is that there's more work lost when the speculation fails.
[...]
Speculative tree building fails when document.write() changes the tree builder state such that the speculative state after the </script> tag no longer holds when all the content inserted by document.write() has been parsed. However, only unusual uses of document.write() cause trouble. Here are the things to avoid:
[...]
Don't write unbalanced trees. <script>document.write("<div>");</script> is bad. <script>document.write("<div></div>");</script> is OK.
The solution is to write the missing single closing quote.
<script type="text/javascript">
for(i=1;i<=50;i++){
document.write("<a href='page.html#"+i+"'>"+i+"</a>");
}
</script>
You have missed out an single quotes.
Try running with below:
for(i=1;i<=50;i++){
document.write("<a href='page.html#"+i+"'>"+i+"</a><br/>");
}
Be careful while using single and double quotes.
Even if you document.write(...) a balanced tree, for example document.write('<span>X</span>'), then you still can get the same error message.
One possible explanation is that you execute that JS code not in the body but in the head of the html, writing something that cannot occur in the head.
For example:
Wrong:
<html>
<meta charset="UTF-8">
<script>
document.write('<span>X</span>');
</script>
</html>
Good:
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<script>
document.write('<span>X</span>');
</script>
</body>
</html>
I know that with basic JS you can read a <script>'s source code like so:
<pre id="scriptContents"></pre>
<script id="myScript" type="text/javascript">
var script = document.getElementById('myScript');
var contents = script.innerHTML;
scriptContents.innerText = contents;
</script>
So my question is: Is there any way similar to this in Greasemonkey/Tampermonkey? I want to be able to read the Greasmonkey script's source code as string.
The reason I'm asking is because the Greasemonkey script is magically included to the page and doesn't have a "physical" representation like the above <script> block.
More background: I'm writing a script but it needs a lot of styles and also a Mustache template which is really hard to provide in JavaScript in a readable form. I want to prevent having the escape every single apostrophe or quote character and also joining the string or adding \ at the end of the line. I found a tricky way to do this, but still looking for alternatives. Here's the current version:
function hereDoc(f) { return f.toString().replace(/^[^\/]*\/\*!/, '').replace(/\*\/[^\/]*$/, ''); }
$('head').append(hereDoc(function() {/*!
<script id="template" type="x-tmpl-mustache">
<div>...
</script>
<style type="text/css">
lots.of #css { code: here; }
</style>
*/}));
I have an app that can generate all sorts of things into the JavaScript strings put on the page. I thought all the escaping were ok, but then I came across a weird problem that I couldn't really find a reason for:
Shouldn't this be legal in an html page:
<script type="text/javascript">
alert("hello </script>");
</script>
'Legal' meaning that it would produce an alert with hello </script>.
Apparently both moz and chrome, on my box at least, cuts the scripting off after the </script> part of the alert string, producing no alert and a messy output. Has anyone run into this, is this a browser bug?
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 type="text/javascript">
alert('hello <'+'/script>');
</script>
<script type="text/javascript">
alert('hello <\/script>');
</script>
You should do like
<script type="text/javascript">
// <![CDATA[
alert('hello </script>');
// ]]>
</script>
To prevent the parsing.
I'm trying to embed some code between <script> </script> tags, pyramid however doesn't like it and gives me
ExpatError: not well-formed (invalid token)
Probably because i have && in my code. I tried using & instead, but then it didn't get interpreted in the browser.
The same thing happens when i try to put it in CDATA block.
When I move the code to a separate js file it works. I'd like to keep it in the same file for now, just to enable quick corrections.
So, how should I do it?
EDIT:
I get the same error even for templates as simple as this one:
<html
xmlns:tal="http://xml.zope.org/namespaces/tal"
xmlns:metal="http://xml.zope.org/namespaces/metal">
<head>
</head>
<body>
<span onclick="alert(true && false);">test</span>
</body>
</html>
I think you're supposed to put && (i.e. two times the HTML entity code).
This should work:
<script type="text/javascript">
//<![CDATA[
// my javascript
//]]>
</script>
Have you tried adding a type attribute to your script tag?:
<script type="text/javascript">
...
</script>
It looks like xhtml issue, as w3c validator reported the same error.
I was thinking if there's a switch to change the document type parsed by chameleon to html, but then it wouldn't be possible to include tal and metal namespaces.
Hence it is expected behavior