Methods to invoke remote scripts - javascript

Scenario
A page invokes a remote script available at this url: http://url.to.script/myScript?ScriptParamsList. Let's assume that:
Async execution is not required.
Displaying output is not required.
The script is called on a button click event. Let Handler() be the javascript event handler:
function Handler()
{
//invoke the remote script
}
Several methods are available to implement Handler() function:
script vs img tag:
document.write('<script src="http://url.to.script/myScript?ScriptParamsList" type="text/javascript"></script>');
document.write('<img src="http://url.to.script/myScript?ScriptParamsList" />');
jQuery .html() vs .load():
$('#TargetDiv').html('<img src="http://url.to.script/myScript?ScriptParamsList" />');
$('#TargetDiv').load('http://url.to.script/myScript?ScriptParamsList');
Question
Which are the advantages and the disadvantages?

document.write will replace your current document when it's called after the document is loaded. Never use this method.
Using <script> allows you to fetch a request from an external domain, without being hindered by the same origin policy. Additionally, in the server's response, you can add and execute JavaScript, which might be useful.
Using .html('<img ...>') makes no sense, unless your server returns an image with meaningful data. If you intend to only trigger a server request, the following would be better:
new Image().src = 'http://url.to.script/myScript?...';
$('..').load is not going to work if the URL is located at a different domain, because of the same origin policy.
I vote for the new Image().src = '..'; method. If you dislike this syntax, and want more jQuery, use:
$('<img>').attr('src', 'http://...');
Note: The result may be cached. If you don't want this to happen, append a random query string, to break the cache (eg. url = url + '&_t=' + new Date().getTime()).

Related

Global JavaScript event for missing resources

I wonder if that is possible to handle missing resources of a web page all togather including missin images from background: url(...) from CSS.
I have checked document.addEventListener("error", eventHandler, true);, window.onerror and also performance.getEntries() but none of them reports missing images referenced from CSS even from inlined styles.
Best base to also handle missing resources from other origins e.g. broken fonts referenced from CDNs.
A possible solution could be to list all resources using window.performance.getEntriesByType("resource"), then try to download each of them using ajax to see if it produces a 404. However there are 2 major drawbacks to consider:
this isn't an event listener, you have to execute the check after a reasonable amout of time to let the browser load all resources, or execute it periodically;
you must avoid to check for dynamic resources which could return a different result from the previous call, or the more dangerous case where a call to a resource produces an update of the data on the remote server (a very trivial example could be a view counter on an image);
there is a chance that the ajax call results in different status code even if the resource is static, for example if the client is on an unstable network and the connection goes down between the two calls.
Anyway here is a starting point:
window.onload = function() {
setTimeout(function() {
var resources = window.performance.getEntriesByType("resource");
resources.forEach(function (resource) {
$.get(resource.name).fail(function(e) {
var msg = 'Failed to load resource '+resource.name+' requested by '+resource.initiatorType;
var div = $('<div/>').text(msg);
$('body').append(div);
});
});
}, 1000);
};
body {
background-image: url('bar.jpg');
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<img src="foo.jpg"/>

Loading external JSON file as a javascript variable

I thought this question would be trivial but I just can't seem to find an answer.
A website (different origin, no control over it) is making available some JSON files. I want some variables of my script to grab the content of those files. I don't care whether it is done synchrnously or not. How would you go ?
using JSONP consist of using your url, with parameters, and add a script file to your page
www.example.com/process?value=1&callback=Func
add the script to your page.
var url = "www.example.com/process?value=1&callback=Func";
var script = document.createElement('script');
script.type= ' text/javascript';
script.src = url;
document.getElementsByTagName("body")[0].appendChild(script);
now you can use the call back function or access the variables that were added from this script.
UPDATE
At the end of your jsonp script you can call your call back function
Ex: php
<?php
if (isset($_GET['callback'])) {
echo $_GET['callback']."();";
// Func(); // will call your function and use your variables.
}
If the remote host does not supply JSONP or CORS, then you will need to place a server-side component on your own domain which fetches the JSON for you and serves it locally.

jquery load() equivalent for offline use

I am looking for an equivalent to jquery's load() method that will work offline. I know from jquery's documentation that it only works on a server. I have some files from which I need to call the html found inside a particular <div> in those files. I simply want to take the entire site and put it on a computer without an internet connection, and have that portion of the site (the load() portion) function just as if it was connected to the internet. Thanks.
Edit: BTW, it doesn't have to be js; it can be any language that will work.
Edit2:
My sample code (just in case there are syntax errors I am missing; this is for the files in the same directory):
function clickMe() {
var book = document.getElementById("book").value;
var chapter = document.getElementById("chapter").value;
var myFile = "'" + book + chapter + ".html'";
$('#text').load(myFile + '#source')
}
You can't achieve load() over the file protocol, no other ajax request is going to work for html files. I have tried even with the crossDomain and isLocale option on without anything success, even if precising the protocol.
The problem is that even if jQuery is trying the browser will stop the request for security issues (well most browsers as the snippet below works in FF) as it allows you to load locale file so you could get access to a lot of things.
The one thing you could load locally is javascript files, but that probably means changing a lot of the application/website architecture.
Only works in FF
$.ajax({
url: 'test.html',
type: 'GET',
dataType: 'text',
isLocale: true,
success: function(data) {
document.body.innerHTML = data;
}
});
What FF does well is that it detect that the file requesting local files is on the file protocol too when other don't. I am not sure if it has restriction over the type of files you can request.
You can still use the JQuery load function in this context:
You would could add an OfflineContent div on your page:
<div id="OfflineContent">
</div>
And then click a button which calls:
$('#OfflineContent').load('OfflinePage.html #contentToLoad');
Button code:
$("#btnLoadContent").click(function() {
$('#OfflineContent').load('OfflinePage.html #contentToLoad');
});
In the OfflinePage.html you could have to have another section called contentToLoad which would display on the initial page.

URL validation/connectivity using javascript

I want to verify if an external url valid/exists/responsive using javascript. For example, "www.google.com" should return true and "www.google123.com" should return false.
I thought to use AJAX for this purpose by testing : if (xmlhttp.readyState == 4 && xmlhttp.status == 200) but it seems that this doesn't work for remote servers(external urls). As my server uses a proxy, i planned to use browser side script so that it automatically uses user's browser proxy if present.
Please tell me do I have to use "AJAX Cross Domain"? How to achieve this, as i simply want to validate a url.
Any way other than using AJAX?
I'm pretty sure this is not possible. Any AJAX that allowed you to call a random page on another domain in the user's context would open up all sorts or security holes.
You will have to use a server-side solution.
The usual way to avoid cross-domain issues is to inject a tag. Tags like image or script kan load their content from any domain. You could inject, say a script tag with type "text/x-unknown" or something, and listen to the tags load-event. When the load event triggers, you can remove the script tag from the page again.
Of course, if the files you are looking for happens to be images, then you could new Image() instead. That way you don't have to pollute the page by injecting tags, because images load when they are created (this can be used to preload images). Again, just wait for the load event on the image.
UPDATE
Okay, it seems I am jumping to conclusions here. There is some differences between browsers on how this can be supported. The following is a complete example, of how to use the script tag for validating urls in IE9 and recent versions of Firefox, Chrome and Safari.
It does not work in older versions of IE (IE8 at least) because apparently they don't provide load/error events for script-tags.
Firefox refuses to load anything if the contenttype for the script-tag is not empty or set to 'text/javascript'. This means that it may be somewhat dangerous to use this approach to check for scriptfiles. It seems like the script tag is deleted before any code is executed in my tests, but I don't for sure...
Anyways, here is the code:
<!doctype html>
<html>
<head>
<script>
function checkResource(url, callback) {
var tag = document.createElement('script');
tag.src = url;
//tag.type = 'application/x-unknown';
tag.async = true;
tag.onload = function (e) {
document.getElementsByTagName('head')[0].removeChild(tag);
callback(url, true);
}
tag.onerror = function (e) {
document.getElementsByTagName('head')[0].removeChild(tag);
callback(url, false);
}
document.getElementsByTagName('head')[0].appendChild(tag);
}
</script>
</head>
<body>
<h1>Testing something</h1>
<p>Here is some text. Something. Something else.</p>
<script>
checkResource("http://google.com", function (url, state) { alert(url + ' - ' + state) });
checkResource("http://www.google.com/this-does-not-exists", function (url, state) { alert(url + ' - ' + state) });
checkResource("www.asdaweltiukljlkjlkjlkjlwew.com/does-not-exists", function (url, state) { alert(url + ' - ' + state) });
</script>
</body>
</html>

For every AJAX call I make, I would like to reload a new java-script

Basically, everytime anybody does anything on this website, I need to retrieve a new javascript from the server (it is a complex math thing, and I am not concerned with speed).
I make the AJAX call, and stick it in the browser in a tag, like this:
getandplaceajax('id=showtotals','main'); // The first is the URL parameter, and the second is the ID of the <div> tag.
While I am doing this, I would like to re-write the java-script file, on the server, and then reload it. It is like this, in the tag.
<script type="text/javascript" src="randomfilename.js"></script>
After this I refresh my object thusly, by retreiving new XML data:
object1.loadXML("http://mywebsite/mydata.xml",
function(xml, url) {eventSource.loadXML(xml,url); });
How do I tell the browser to re-load the java-script file (force a re-load, on demand)?
I tried to interactively load the java-script into the portion of the page, but this is an iffy situation given that AJAX is asynchronous and unpredictable in the event chain.
And I am not doing page loads, so referencing the java-script with a unique number parameter (to prevent caching) isn't an option.
An extra $50 in the church offering plate next Sunday, in your name, for a solution.
Thanks in advance
Jeff
There is no need to make an Ajax call if you just need to load a JavaScript file. You can just append a new script tag to the page.
var scr = document.createElement("script");
scr.type="text/javascript";
scr.src="myFile.js";
document.body.appendChild(scr)
If you are calling the same file each time you need to force it to fetch the new file by adding a querystring value
scr.src="myFile.js?ts=" + new Date().getTime();
On the server you can request a php, servlet, .NET page, etc and have it return the JavaScript code. It does not have to be a js file. Just set the content type to be JavaScript and your browser will not care.
If you are not using any library, you can use what Facebook is doing
http://developers.facebook.com/docs/reference/javascript/
var e = document.createElement('script'); e.async = true;
e.src = document.location.protocol +
'//connect.facebook.net/en_US/all.js';
document.getElementById('fb-root').appendChild(e);
to load in a new script this way. You can also change the src of the script tag, to something like 'myfile.js?timestamp=' + (new Date()).getTime(), or you can return javascript with <script> tag around it and put it into a div or return javascript and eval them, similar to how RJS is handled.

Categories