Serving Dynamic JavaScript With ColdFusion

Posted By : todd sharp Posted At : February 17, 2009 9:42 AM Posted In: JavaScript, ColdFusion

8

I know the title doesn't sound terribly exciting, but bear with me, the topic is actually pretty cool. A friend asked me this morning if there was a way to 'import' a JavaScript file (in this case it was jQuery) from another JavaScript file.

It is an interesting question for sure. Your first thought is probably the <script> tag, but the <script> tag is an HTML tag. If you're serving a pure JS file you can't just slap a <script> tag in and go on your merry way.

I know jQuery itself has dynamic script loading methods, so I'm sure it can be done via script, but I was curious as to his implementation since I thought CF could provide what I believe to be a more elegant solution. He told me that he is hosting a JS file that users can point to to include his content on their page. Think of Google Ads for example - you put their script on your page and the magic 'just happens'. In his case he wanted to include jQuery in his script, but couldn't think of a way to get it done.

The answer is pretty simple, and in my previous testing it works flawlessly. Just have folks point to a ColdFusion file that serves up the JavaScript. Here is a quick example.

one.js:

one = function(){
    return 'hi, i\'m file one';
}

two.js:

two = function(){
    return 'hi, i\'m file two';
}

jsInclude.cfm:

<cfcontent type="text/javascript">
<cfinclude template="one.js" />
<cfinclude template="two.js" />

Note: the key to jsInclude.cfm is to include the necessary JavaScript files via cfinclude, not via a script tag. Remember that cfcontent is going to serve this content as text/javascript - so a <script> tag won't work - it's HTML.

index.cfm:

<html>

<head>
<script src="jsInclude.cfm" type="text/javascript"></script>
<script>
getStuff = function(){
    var o = document.getElementById('output');
    o.innerHTML += one();
    o.innerHTML += '<br />';
    o.innerHTML += two();
}
</script>
</head>

<body>
    <input type="button" id="getStuffFromJS" onclick="javascript:getStuff();" value="get stuff" /><br />
    <div id="output"></div>
</body>

</html>

And that's it. I've combined external, raw JS files into a single CFM proxy and included that in my page via a <script> tag. Here is a quick demo.

Related Blog Entries

Comments (8)

Timothy Farrar's Gravatar Did you try this?
jQuery.getScript( url, [callback] );

Not entirely sure, but from the looks of things this will fit your use case, and is a bit simpler!

todd sharp's Gravatar @Timothy: the question is, how does jQuery get in the script in the first place? That is the problem being solved here - including jQuery in the remote script.

It's just as easy to write the script to the DOM to include jQuery, but I think this method gives you a little more control and lets you be dynamic. For example, you could pass variables to the CFM proxy via the URL, etc.

Tony Nelson's Gravatar I've never thought about using a .cfm template as a script source, but it seems like it could be pretty useful since you could then reference application/session/cgi variables directly in the script.

On a side note, have you noticed any improvements in performance since you're only making 1 remote script call? Or is it outweighed by any overhead in executing the ColdFusion inside the script?

todd sharp's Gravatar I can't say I've paid much attention to performance, but another advantage of being on the server is that you can gzip/compress your script before serving it. But like you said, is that outweighed by the overhead of doing the server side processing? Not sure...

Thomas Messier's Gravatar I'm guessing that the downside is that the script file can't be cached by the browser, right? Not necessarily the end of the world, but a good thing to know lest somebody go crazy and convert all their *.js files to *.cfm files.

todd sharp's Gravatar @Thomas - I don't see why it wouldn't be cached. I had a friend confirm in Firebug that it is. I'm running an older version of FireFox without Firebug at the moment so I can't confirm. Did you check it yourself?

Thomas Messier's Gravatar No, haven't checked. But I guess if it's cacheable it's probably important to mention that aspect of things, because if people start serving up dynamic content into their JS file (as opposed to your case where it's really to join a bunch of files), you can run into problems if a cached file with old dynamic values is served to a user.

todd sharp's Gravatar Good point - I'll have to do some experimenting tonight to check a bit more on the implications.