Jump to content

Dynamically loading JavaScript files


gamblor01

Recommended Posts

Hi all,

 

I have done some search on the net and found some solutions to dynamically load up JavaScript files.  It looks pretty simple, just reference the HEAD element of the document via DOM and append a child.  I only want to do this in the case that a particular JavaScript file is available, and I believe I have an AJAX solution do that.  Here are the two functions that I wrote:

 

function isReachableURL(url)
{
var request = false;
if (window.XMLHttpRequest)
{
	request = new XMLHttpRequest;
}
else if (window.ActiveXObject)
{
	request = new ActiveXObject("Microsoft.XMLHttp");
}

if (request)
{
	request.open("GET", url);
	if (request.readyState == 4 && request.status == 200)
		return true;
}

return false;
}


function addJavaScriptFile(path)
{
var fileRef = document.createElement('script');
fileRef.setAttribute("type","text/javascript");
fileRef.setAttribute("src", path);
fileRef.setAttribute("id", gpsGateDomId)
document.getElementsByTagName("head")[0].appendChild(fileRef);
}

 

 

Armed with these two functions, I can test for the existence of .js file on an external server and reference it if it's reachable.  The reason I am doing this is to facilitate some GPS functionality in the application that I work on.  We are relying on a program called GpsGate to gather coordinates from a USB/bluetooth GPS device.  GpsGate works by launching a small HTTP server that hosts some JavaScript files, and via cross scripting you can obtain your position, altitude, etc.  More info can be found here:

 

http://forum.gpsgate.com/topic.asp?TOPIC_ID=6102

 

 

Their server is ALWAYS at http://localhost:12175/javascript/GpsGate.js -- assuming that GpsGate is running of course!  So my goal is to add a script tag to my page that references http://localhost:12175/javascript/GpsGate.js as the source.  In fact, I did this and all of my code works fine.  The problem is, for users that do not have GpsGate installed, the browser will output an error that it was unable to load that JavaScript file.  For example, if you go into the developer tools in Chrome (CTRL+SHIFT+I) and look, there will be an error that says:

 

GET http://localhost:12175/javascript/GpsGate.js undefined (undefined)

 

 

Of course other developers are complaining about this and our users will no doubt complain eventually as well.  So instead of placing this file into the HEAD tag of the page every time, I want to append it dynamically (only in the case that the user has chosen to do something which involves GPS).  I am able to dynamically add the child element to HEAD -- I see it get added in Chrome's debugger if I inspect the children of document.getElementsByTagName("head")[0].  However, it still seems that the typeof(GpsGate) is undefined.

 

If I'm understanding correctly, the SCRIPT tag seems to be getting appended under HEAD, but it's almost as if that script is never executed.  Do I need to do something special for that script file to execute after appending it in the DOM tree?  If it helps, here is the script file that I see when I hit http://localhost:12175/javascript/GpsGate.js in my browser.  It's some strange anonymous function syntax that I'm not familiar with in JavaScript.  Any body know what to do to get this function to execute in JavaScript after appending the SCRIPT tag in the DOM tree?  I added an alert() in this script to see if it would print anything when I added it in the DOM tree and it did not -- reinforcing the idea that it's being appended in DOM but never executed.  If I add the script manually into the HEAD tag then it does show my alert box.

 

//
// Copyright Franson Technology AB - GpsGate.com
// franson.com - gpsgate.com
//

(function()
{
if (typeof(GpsGate) == 'undefined')
{
	GpsGate = {};
}

var _url = 'http://localhost:12175/gps';

var _scriptCounter = 0;

function buildQueryString(params)
{
	var strParams = '';
	for (prop in params)
	{
		strParams += '&' + encodeURIComponent(prop) + '=' + encodeURIComponent(params[prop]);
	}
	return strParams;
}

function xssCall(methodName, params, callback)
{
	var id = _scriptCounter++;
	var scriptNodeId = 'GpsGateXss_' + id;

	var poolName = methodName + '_' + id;

	GpsGate.Client._callback[poolName] = function(/*arguments*/)
	{
		var scriptNode = document.getElementById(scriptNodeId);
		scriptNode.parentNode.removeChild(scriptNode);
		delete GpsGate.Client._callback[poolName];
		scriptNode = null;

		callback.apply(this, arguments);
	};

	var callUrl = _url + '/' + methodName + '?jsonp=' +	('GpsGate.Client._callback.' + poolName) + buildQueryString(params);

	var script = document.createElement('script');
	script.type = 'text/javascript';
	script.id = scriptNodeId;
	// script.charset = 'utf-8'; // necessary?

	var noCache = '&noCache=' + ((new Date()).getTime().toString().substr(5) + id);
	script.src = callUrl + noCache;

	// todo: use this method on non-conforming browsers? (altough both IE6 and PC-Safari seems to work anyway)
	// document.write('<script src="' + src + '" type="text/javascript"><\/script>');

	document.getElementsByTagName('head')[0].appendChild(script);
	script = null;
}

// API
GpsGate.Client = {
	Copyright: 'Franson Technology AB - GpsGate',

	getGpsInfo: function(callback)
	{
		xssCall('getGpsInfo', {}, callback);
	},

	getVersion: function(callback)
	{
		xssCall('getVersion', {}, callback);
	},

	// -----
	_callback: {}
};

})();

Link to comment
Share on other sites

Hmm...well I sort of got things working by using dojo.  The following works to dynamically load the external .js file:

 

function addJavaScriptFile(path)
{
dojo.io.script.get (
{ 
	url: gpsGateURL, 
	load: function()
	{
		// signal that this has been loaded already
		gpsGateLoaded = true;
	} 
});
}

 

 

However, it turns out my isReachableURL() function (which was previously commented out) doesn't work.  Apparently this is due to the same-origin policy:

 

http://stackoverflow.com/questions/5573360/test-url-availability-with-javascript

 

 

 

This is a bit of a bummer because I'm not sure how to solve this yet.  I can't let the server test for the existence of the URL because the whole point is that the URL is local to the client (i.e. localhost is the client system and *NOT* the server).  GpsGate retrieves coordinates and then outputs that information to the "browser".  This allows client systems to have an attached GPS and our system to show their coordinates.  If the GPS were attached to the server then it would be pointless -- it would show the server's location and not the end-user's location.  I was originally trying to test for the existence of the URL on the server side (in Java) until I realized that it was always returning false because GpsGate wasn't running on the server.  I'm not sure how to solve this problem yet.  :(

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.