The task seems to be pretty easy: how to include a Javascript file in xml-document so that at least Opera and Firefox could actually parse it and execute the code?
Add a script stating XHTML namespace, it will run just fine.
<xhtml:script xmlns:xhtml="http://www.w3.org/1999/xhtml"
src="file.js"
type="application/javascript"/>
See also
http://www.ibm.com/developerworks/xml/library/x-ffox3/
If I get you, you want an XML document to run javascript when viewed in a browser?
This is not part of the XML standard, and as such will not be suppoted until it is (I assume this will never be supported because XML is not intended for display, but data). If you are talking about XHTML then this is a different matter.
--
Edit: just to clarify my answer.
XML was never intended to be a display markup like HTML, thats why XHTML was developed (HTML that conforms to XML standards). Browsers have been made to interpret XHTML in a certain way, but XML is simply raw data.
If you want your XML to run additions such as JavaScript you will want to consider using XSLT to transform your XML into XHTML and therefore take advantage of a browsers capabilities.
<script xmlns="http://www.w3.org/1999/xhtml"><![CDATA[
alert('Hello');
]]></script>
Or for external javascript:
<script xmlns="http://www.w3.org/1999/xhtml" src="external.js"></script>
Works in Firefox and Opera.
I did this:
XSLT:
<xsl:value-of select="/label[#id='MyScript']/text()" disable-output-escaping="yes"/>
XML:
<label id="MyScript"><![CDATA[
<script type="text/javascript">
alert("Hello world");
</script>
]]></label>
Embed the XML and the Javascript in an XHTML document and then use the vast and well-documented capabilities of dynamic HTML.
You'll get something up and running much faster than you will by reasoning that since some browsers implement weak and poorly-documented CSS styling of XML documents, therefore they must support the execution of Javascript embedded in XML, as though there were any connection whatsoever between those two ideas.
Similar to the above, but that could error because the <![CDATA[ and ]]> portions are not valid code. If you're putting it into an XSL script, you can just as well put a JS comment mark before these beginning and ending elements.
I also have used the xsl:text element to output the <![CDATA[ portion. This portion may be a bit of cheat, but it results in well-formed XML. An example from within an xsl:choose block might be...
...
<xsl:when test='name()="script"'>
<script>
<xsl:for-each select='#*'><xsl:copy-of select='.' /></xsl:for-each>
<xsl:text disable-output-escaping='yes'>
// <![CDATA[
</xsl:text>
<xsl:copy-of select='./text()' />
<xsl:text disable-output-escaping='yes'>
//]]>
</xsl:text>
</script>
</xsl:when>
...
Walking through the pieces...
Detect a <script> element.
Replicate <script> tag for the output.
Be sure to preserve the tag attributes in the output with a quick xsl:for-each line.
Output the non-escaped text: // <![CDATA[. The // renders the rest of the line as a comment and thus prevents a JS error.
Copy the text contents of the <script> tag. NOTE: You must preseve the new-line (either as above or some other way) so that the commented out line before it does not end up on the same line as this one. Obviously, if it does, it will comment out this line as well. Preserving the one after is not essential, but is keeps the aesthetics of the two matching CDATA tags.
Output the non-escaped text: // ]]>. This ends the CDATA block, and again, the CDATA marking is ignored by the browser when reading the JS.
Close the block with a </script> tag, of course.
And, if you're using it in a xsl:choose block, close then xsl:when.
Only steps 2, 3, 5, & 7 actually copy the script block. The rest is busywork to make it work.
Transforming a block such as...
...
<script type='javascript'>alert('Hello World!');</script>
...
Then becomes,
...
<script type='javascript'>
// <![CDATA[
alert('Hello World!');
// ]]>
</script>
Effectively preserved, and readable both by XML as well as a browser.
A function that should help you is the eval() function. This function will evaluate any string you pass to it as Javascript.
Also, it's possible to parse XML in Javascript. Just google "javascript xml parser".
Combine these two ideas, and you'll be on your way.
If you simply want to put javascript in the XML file:
<xml>
<js script="1">
here is some javascript;
here is more javascript;
</js>
<js script="2">
here is even more javascript;
jere is even more javascript;
</js>
</xml>
Related
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'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>\)
I'm currently teaching myself some AJAX through jQuery.
I've written a straight forward get request to load in data from an xml file into a section with a class of container.
Here is my html file:
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<section class="container">
</section>
<script src="http://code.jquery.com/jquery-1.11.0.min.js" type="text/javascript" charset="utf-8" async defer></script>
<script src="xmlFeed.js" type="text/javascript" charset="utf-8" async defer></script>
</body>
</html>
I am using a local xml file after i created to dummy post on a WordPress site and got the feed.
Here is the xml file:
<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
>
<channel>
<title>Biz-Tech.ie » Biz-Tech News</title>
<atom:link href="http://www.biz-tech.ie/category/biz-tech-news/feed/" rel="self" type="application/rss+xml" />
<link>http://www.biz-tech.ie</link>
<description></description>
<lastBuildDate>Sat, 11 Oct 2014 17:39:16 +0000</lastBuildDate>
<language>en-US</language>
<sy:updatePeriod>hourly</sy:updatePeriod>
<sy:updateFrequency>1</sy:updateFrequency>
<generator>http://wordpress.org/?v=4.0</generator>
<item>
<title>News</title>
<link>http://www.biz-tech.ie/news/</link>
<comments>http://www.biz-tech.ie/news/#comments</comments>
<pubDate>Sat, 11 Oct 2014 17:39:16 +0000</pubDate>
<dc:creator><![CDATA[Michael]]></dc:creator>
<category><![CDATA[Biz-Tech News]]></category>
<guid isPermaLink="false">http://www.biz-tech.ie/?p=170</guid>
<description><![CDATA[Output Box – Random strings/passwords will display here. Load objects used for random string generation into the “Object Input Box” above. Objects above can be characters, words, sentences, etc. Test by clicking the “Generate random strings” button above to generate 10, 14 character, random strings from the default input objects. NOTICE: Tool uses Javascript method Math.random() pseudorandom generator to obtain […]]]></description>
<content:encoded><![CDATA[<p>Output Box – Random strings/passwords will display here.<br />
Load objects used for random string generation into the “Object Input Box” above. Objects above can be characters, words, sentences, etc.<br />
Test by clicking the “Generate random strings” button above to generate 10, 14 character, random strings from the default input objects.<br />
NOTICE: Tool uses Javascript method Math.random() pseudorandom generator to obtain random string. Do not use for critical random results.<br />
Privacy of Data: This tool is built-with and functions-in Client Side JavaScripting, so only your computer will see or process your data input/output.</p>
]]></content:encoded>
<wfw:commentRss>http://www.biz-tech.ie/news/feed/</wfw:commentRss>
<slash:comments>0</slash:comments>
</item>
</channel>
</rss>
And finally here is the ajax GET request along with a function to parse the xml into the container section in my html:
$(doccument).ready(function() {
$.ajax({
type:"GET",
url:"feed.xml",
dataType:"xml",
success:xmlParser
});
});
function xmlParser(xml) {
$(xml).find("item").each(function(){
$("#container").append('<h3>'+ $(this).find("title").text()+'</h3><br />'
'<a href="'+ $(this).find("link").text()+'></a>'
'<p>'+ $(this).find("description").text()+'</p>'
'<p><h5>Author: '+ $(this).find("dc:creator").text()+'</h5></p>'
);
});
}
The function isn't working and for the life of me I have no idea why as I can see an syntax errors.
Any advice would be greatly appreciated.
Thanks.
A few problems with your code.
1). The way you are concatenate strings in javascript is not correct. Use this syntax:
$(xml).find("item").each(function(){
$(".container").append('<h3>'+ $(this).find("title").text()+'</h3><br />' +
'' +
'<p>'+ $(this).find("description").text()+'</p>' +
'<p><h5>Author: '+ $(this).find('dc\\:creator, creator').eq(0).text()+'</h5></p>'
);
});
Note + operator, it is used for string concatenation.
2). One more problem. You missed a closing quote in link construction string, which breaks HTML and hides all subsequent content:
''
^-- add this guy here
3). One more thing: your selector must be $(".container") since container is a class, not id.
4). And finally there is one more little detail about how you should retrieve dc:creator node. Since this node is namespaced you need to escape it like this:
.find("dc\\:creator")
However it still doesn't guarantee that it will work in all browsers. You probably should do something like this:
$(this).find('dc\\:creator, creator').eq(0)
You provide two selectors here. The second selector creator will work in Chrome, and the first (escaped) in Firefox.
5). Also just in case, doccument is a probably a typo, but anyway it should be document.
Demo: http://plnkr.co/edit/0Z2tJJ3JANtJq30CNUDD?p=preview
You wrote doccument instead of document in your $(doccument).ready.
The key to your problem is "I am using a local xml file ...". If you look at your console I am pretty sure that you are getting an "Access-Control-Allow-Origin error". This is a browser model security problem. Have a read here if you need more info.
In short though Access-Control-Allow-Origin errors occurs when you call a Web Service such as do a GET request for an XML file, from a domain that is different from the one hosting your HTML page. In you case I believe that you are your HTML file is on your hard drive while the Web Service is called on the localhost.
For development purposes you can use this chrome plugin. That will work for now.
How do i write a Jsp page which opens JSbox.
main vulnerabilities that apply to this eg.
I'm just going to worry about the cross-site-scripting problems caused by HTML and JS injection. CSRF doesn't seem to be an issue yet because just alerting “hello” doesn't have any active side-effects that you would have to be logged in to do.
The bonehead way of doing it:
<script type="text/javascript">
alert('Hello, <%= request.getParameter("name") %>');
</script>
This suffers from JS injection because there is no JS-escaping inside a JS string literal:
name=');execute_arbitrary_code();'
and also suffers HTML injection because the enclosing script block can be closed early:
name=</script><script>execute_arbitrary_code();//
Unfortunately there is no standard tag in JSP that will escape text in a JS string literal (that is itself in an HTML script block). You can write and use your own tag to do it, or reuse a library that defines one. For example OWASP ESAPI has:
<script type="text/javascript">
alert('Hello, <esapi:encodeForJavaScript>${param.name}</esapi:encodeForJavaScript>');
</script>
But it is often easier to avoid encoding into JS, and instead push data through the DOM. Because the DOM is plain HTML, you only need normal markup escaping, which JSP has natively in the <c:out> tag.
<input type="hidden" id="name-parameter" value="<c:out value="${param.name}"/>"/>
<script type="text/javascript">
var name = document.getElementById('name-parameter').value;
alert('Hello, '+name);
</script>
This aids in the long-term goal of keeping your JS separate from your markup and server-side code. data- attributes are another good way to pass data from markup to JS.
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