I have a page that only contains a string and need to read it from a page in a different domain. I have tried to do it via a dynamic script hack (to avoid the security restrictions) and can read that string but cant bring it in a callback to keep working with it in a variable.
My problem is that I need to do it only using javascript.
Here is the code that I am currently using:
index.html:
<html>
<head>
<script type="text/javascript">
function xss_ajax(url) {
var script_id = null;
var script = document.createElement('script');
script.setAttribute('type', 'text/javascript');
script.setAttribute('src', url);
script.setAttribute('id', 'script_id');
script_id = document.getElementById('script_id');
if(script_id){
document.getElementsByTagName('head')[0].removeChild(script_id);
}
document.getElementsByTagName('head')[0].appendChild(script);
}
var url = "http://otherdomain.com/ping.html";
xss_ajax(url);
</script>
</head>
<body>
</body>
</html>
ping.html:
1|1739
Very much thanks and sorry my english.
Your result from ping.html dose not have any variables defined, if you say
made an object like
result = [1,1739];
and in index.html you declared
var result = [];
then you could work with that.
Related
I need to append timestamp to the javaScript file in tag url to avoid caching.
This function found here in stackoverflow seems to do it:
<script type="text/javascript">
(function(){
var randomh=Math.random();
var e = document.getElementsByTagName("script")[0];
var d = document.createElement("script");
d.src = "TESTINGX.JS?x="+randomh+"";
d.type = "text/javascript";
d.async = true;
d.defer = true;
e.parentNode.insertBefore(d,e);
})();
But the problem is that inside the file testingx.js I've placed the following code:
var hello = "Hello World!";
And for some reason the variable doesn't get the global scope (or maybe the problem is other).
My html is the following:
<!DOCTYPE html>
<HTML><HEAD>
<script type="text/javascript">
(function(){
var randomh=Math.random();
var e = document.getElementsByTagName("script")[0];
var d = document.createElement("script");
d.src = "TESTINGX.JS?x="+randomh+"";
d.type = "text/javascript";
d.async = true;
d.defer = true;
e.parentNode.insertBefore(d,e);
})();
</script>
</HEAD><BODY>
<h1>WiFi Mini Web Server</h1>
<script>
document.write(hello); //hello var is contained in the TESTINGX.JS file\n\
</script>
</BODY></HTML>
If you want the external script to block everything else until it loads but still need to load it from a dynamic URL (it sounds like you do), you should be able to document.write the script element directly instead of using the DOM methods.
<!DOCTYPE html>
<html><head>
<script>
var randomh = Math.random();
document.write('<script src="TESTINGX.JS?x=' + randomh + '"></' + 'script>');
</script>
</head><body>
<h1>WiFi Mini Web Server</h1>
<script>
document.write(hello); // hello var is contained in the TESTINGX.JS file
</script>
</body></html>
http://jsbin.com/ixagud/2/edit
You code for cache busting, also happens to ensure that the script is loaded in a "lazy", "non-blocking" manner. Which means the TESTING.js is loaded after your DOM is loaded. Which also means that the document.write script is run before the js file has loaded, and added the required var to the global scope.
There can be several solutions:
1. Remove defer and async from your loading script
Ensure variables from your script are accessed on your page, only after the script is actually loaded
Better yet, don't try to handle cache busting through clever javascript (I am assuming the html is question is served using some sort of server technology like a jsp or php script). Use the server technology to add a parameter with a random number or timestamp to the usual script tag in the html
Instead of using a script to bust cache, use a normal script tag, with a parameter that is same as the timestamp in millis, as on the day when you make the build, and embed in your microcontroller / server. Treat this like a version number of the js file. So clients can use the file cached in their browser, provided the version number is the latest.
This ant task http://code.google.com/p/ant-web-tasks/wiki/CacheBusting is a good way to implement point no 4. I have had good experience with it.
Hope this helps.
try this
<script type="text/javascript">
(function(){
var randomh=Math.random();
var e = document.getElementsByTagName("script")[0];
var d = document.createElement("script");
d.src = "TESTINGX.JS?x="+randomh+"";
d.type = "text/javascript";
d.async = true;
d.defer = true;
e.parentNode.insertBefore(d,e);
document.write(hello);
})();
</script>
I want to use Google API inside a js file and how can I use it? I tried to use google.load() directly in the js file but was told that google is not defined. Then I tried to use the following code
var s = document.createElement('script');
but was told that document is not defined.
What should I do to use google api inside a js file? Thank you.
Here what I want to use is the Google Feed API.
The html code I used is
<!DOCTYPE HTML>
<html>
<head>
<title>
Example
</title>
<script src="https://www.google.com/jsapi" type="text/javascript"></script>
</head>
<body>
<div>
<p id="computation_results">please wait, computing … </p>
</div>
<script>
var worker = new Worker('numberworker.js');
worker.postMessage({first:123,second:456});
worker.onmessage = function (event)
{
alert(event.data);
document.getElementById('computation_results').textContent = event.data;
};
</script>
</body>
</html>
and the js file where I want to use the api is
// Our callback function, for when a feed is loaded.
function feedLoaded(result) {
if (!result.error) {
var container = document.getElementById("content");
container.innerHTML = '';
for (var i = 0; i < result.feed.entries.length; i++) {
var entry = result.feed.entries[i];
var div = document.createElement("div");
div.appendChild(document.createTextNode(entry.title));
container.appendChild(div);
}
}
}
function OnLoad() {
var feed = new google.feeds.Feed("http://www.digg.com/rss/index.xml");
feed.load(feedLoaded);
}
onmessage = function (event)
{
var fileref=document.createElement('script');
var filename="https://www.google.com/jsapi";
fileref.setAttribute("type","text/javascript");
fileref.setAttribute("src", filename);
document.getElementsByTagName("head")[0].appendChild(fileref);
// google.load("feeds", "1");
// google.setOnLoadCallback(OnLoad);
var first=event.data.first;
var second=event.data.second;
postMessage("Work done! "+ " "+first+" "+second);
};
You need to include the API before you can use it. Try putting this in your head block:
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
To load the feed API, you can then have another script block like this:
<script type="text/javascript">
google.load("feeds", "1");
var feed = new google.feeds.Feed("<<url here>>");
...
</script>
I would check to make sure your html is validated first, or put up a link to a test file. Any slightest error can cause you to get any number of errors. I tried the following code in a file by itself, wrapped in tags, and was able to load the api. To load a javascript file using javascript you would use the following
var fileref=document.createElement('script');
var filename="https://www.google.com/jsapi";
fileref.setAttribute("type","text/javascript");
fileref.setAttribute("src", filename);
document.getElementsByTagName("head")[0].appendChild(fileref);
Then after it you use the api calls
google.load(....)\
EDIT:
You are using html5 web workers, that use process outside of the browser, to create a script. This is not possible due to html5 workers do not have access to the DOM. http://www.sitepoint.com/javascript-threading-html5-web-workers/
You would have to create it outside of the worker or include in a script element
I am trying to load another JS file from a JS file.
From my JavaScript file run.js, I have the following:
document.write("<script type='text/javascript' src='my_script.js'></script>");
alert(nImages);
In side my_script.js I have the following:
<SCRIPT language="JavaScript" type="text/javascript">
<!--
nImages = 6;
//-->
</SCRIPT>
But I can't seem to get it to alert the nImages from my_script.js file.
You could do this:
var script = document.createElement('script');
script.src = 'my_script.js';
script.type = 'text/javascript';
script.onload = function () {
alert(nImages);
};
document.getElementsByTagName('head')[0].appendChild(script);
You should not use HTML inside of your script file. Your script file my_script.js should have only this in it.
nImages = 6;
Additional note: you don't need language="JavaScript" or the <!-- or //-->. Those are old conventions not needed for modern browsers (even IE6). I'd also avoid using document.write() in your JS as it has performance implications. You may want to look at a library such as RequireJS which provides a better way to load other JS files in the page.
I also have a code snippet on Github inspired by Steve Souders that loads another file via straight JS.
var theOtherScript = 'http://example.com/js/script.js';
var el = document.createElement('script');
el.async = false;
el.src = theOtherScript;
el.type = 'text/javascript';
(document.getElementsByTagName('HEAD')[0]||document.body).appendChild(el);
This will append the other script to the element (if it exists) or the of the page.
Javascript files should not have HTML in them. They should consist entirely of Javascript code, so my_script.js should contain only:
nImages = 6;
This still won't work because when you write the new script tag into the document it doesn't run immediately. It is guaranteed that run.js finishes running before my_script.js starts, so nImages is undefined when you alert it and then becomes 6 later. You'll see that this works:
document.write("<script type='text/javascript' src='my_script.js'></script>");
function call_on_load(){
alert(nImages);
}
If the contents of my_script.js are:
nImages = 6;
call_on_load();
Edit
Since you said in a comment that you can not edit my_script.js you can do this although it is not nearly as nice a solution:
// Force nImages to be undefined
var undefined;
window.nImages = undefined;
document.write("<script type='text/javascript' src='my_script.js'></script>");
(function is_loaded(cb){
if(typeof window.nImages == 'undefined')
setTimeout(function(){ is_loaded(cb); }, 100);
else
cb();
})(function(){
// This is executed after the script has loaded
alert(nImages);
});
This is not a nice solution, however, since it will continue polling indefinitely if there is an error loading the script.
EDIT
You posted in a comment the file you want to include, which has the <SCRIPT at the top. This file is useless and you can't do anything about it client side. You'd have to write a server side script to load the file as text in which case you can just parse it for the value you want.
Instead of:
<script src="/scripts/myJsFile.v1.js" type="text/javascript></script>
Have something like
<script src="/scripts/myJsFile." + versionVar + ".js" type="text/javascript></script>
This way when we update the js version files the user won't have to clear their cache.
Not in that way, because you're mixing HTML and JavaScript together. HTML does not have JavaScript variables available.
What you can do, however, is adding the <script> tag dynamically, i.e. through JavaScript. That way, you obviously are able to use variables:
<script>
var versionVar = "1.0";
window.addEventListener('load', function() { // on load
var scriptTag = document.createElement('script'); // create tag
scriptTag.src = "/scripts/myJsFile." + versionVar + ".js" // set src attribute
scriptTag.type = "text/javascript"; //set type attribute
document.getElementsByTagName('head')[0].appendChild(scriptTag); // append to <head>
}, false);
</script>
Check out how Google loads their Analytics. Then maybe try something similar like:
(function() {
var versionVar = 9;
var ga = document.createElement('script');
ga.type = 'text/javascript';
ga.src = 'http://www' + '.google-analytics.com/ga' + versionVar + '.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(ga, s);
})();
You can't do this in your HTML file directly. But still you can do this inside an script tag if versopnVar is a JavaScript variable in your window context:
<script type="text/javascript">
var script = document.createElement('script');
script.setAttribute('src', '/scripts/myJsFile.' + versionVar + '.js');
script.setAttribute('type', 'text/javascript');
document.body.appendChild(script);
</script>
At the end, it's not a good aproach doing this. Please read this article at a list apart to get informed.
Alternative Style: Working With Alternate Style Sheets
It would probably be better to do something like
<script src="/scripts/myJsFile.js?v1" type="text/javascript></script>
Then, when you make and update:
<script src="/scripts/myJsFile.js?v2" type="text/javascript></script>
Which will cause most browsers to pull the file rather than pull from cache. This means that you won't have separate JS files. But will just be forcing the user to pull the most recent.
Also, if you want it to always pull the file you can, in a similar manner, append a random int.
You cannot do that straight out.
One way is with some server side code.
For example in php:
<?php $version = "1.0"; ?>
<script src="/scripts/myJsFile.<?php echo $version ?>.js" type="text/javascript></script>
Not exactly that way, but you can create a new script node with e.g. document.createElement and add it to the page.
var s = document.createElement("script");
s.src = ...
document.body.appendChild(s);
You can also use the document.write call to do the same...
You'd have to update your page to update the variable. Also, you'd have to update your javascript file name every time you changed it.
You can use a query string to make your JS unique.
<script src="/scripts/myJsFile.js?version=2" type="text/javascript></script>
marshall & I had the same Idea.
Also, you'd have to update your HTML file every time you updated your Javascript file.
I want to include a script tag, while providing a parameter to it. This is what I came up with so far
Provide a parameter to script URL (cons: generate multiple JS files)
<script src="http://example.com/something.js?P=123" type="text/javascript"></script>
Hide parameter in script tag (cons: same as #1)
<script src="http://example.com/scripts/123/something.js" type="text/javascript"></script>
Google Analytics way (cons: ugly, complicated, global variables)
<script type="text/javascript" charset="utf-8">
var _something = _something || 123;
(function() {
var s = document.createElement('script');
s.type = 'text/javascript';
s.src = 'http://example.com/something.js';
var ss = document.getElementsByTagName('script')[0];
ss.parentNode.insertBefore(s, ss);
})();
</script>
The best thing is to define things (functions &c) in the external script but execute nothing. Then have an inline script that calls functions/methods defined in the external script.
<script src="http://example.com/something.js" type="text/javascript"></script>
<script type="text/javascript">
something(123);
</script>
If the way the script is executed, depends on how it's called, you can add params like your option 1.
Other ways are:
<script params='{"abc": 123}' src="script.js"></script><!-- params is a non standard, non official attr that the script will read -->
or
<script>var _abc = 123;</script>
<script src="script.js"></script>
or even
<script src="script.js#abc=123"></script>
I have to agree with #outis though: load the same thing for everybody, always, and execute it like you/the client want(s) afterwards.
I do this for a cross-sub-domain XHR handler that I have. I call it as:
<script type="text/javascript" src="xd.js#subdomain"></script>
and then in the script, parse it as such (using jQuery):
$('script').each(function(){
if((src = this.src).indexOf('xd.js') < 0){ return; }
xds = src.substr(src.indexOf('#') + 1).split(',');
// do stuff with xds
});
Your first example does not need to generate multiple files. It can be used by JavaScript alone, by detecting window.location.href and parsing it (you might find the likes of http://phpjs.org/functions/parse_url:485 and http://phpjs.org/functions/parse_str:484 helpful in doing this: var queryString = parse_str(parse_url(window.location.href).query); ).
However, if you use something like #P=123 instead of ?P=123, you won't cause another download of the file by your users, so I'd recommend that instead (in which case change "query" in the above code sample to "fragment").
Another possibility is using the HTML5-reserved data-* attributes, and detecting their values within your script:
<script src="http://example.com/something.js" data-myOwnAttribute="someValue" data-anotherCustomAttribute="anotherValue"></script>
The script would then detect along these lines:
(function () {
function getScriptParam (attr) {
var scripts = document.getElementsByTagName('script'),
currentScript = scripts[scripts.length-1];
return currentScript.getAttribute('data-' + attr); // in future, could just use the HTML5 standard dataset attribute instead: currentScript.dataset[attr]
}
var myOwnAttribute = getScriptParam('myOwnAttribute');
// ... do stuff here ...
}());
The real advantage of Google's ugly API is that it allows developers to drop in that code in the <head> of the document (considered proper form), while still acting asynchronously in a cross-browser way. I think they could indeed avoid the global had they combined their dynamic script-tag technique with either of the above approaches.