As if my initial amazement of the simplicity of ajax was not enough, as part of my job at Outbrain I have recently come across an even simpler (and in some ways, better) method to implement asynchronous client-side requests to the server. In fact, it is SO simple you would be tempted to use it even when you don’t really need it!
First, I must clarify and say that this other method does not really come to replace the “traditional” AJAX path (involving the use of the native javascript ‘XMLHttpRequest’ object), but simply poses an alternative which might better suit some specific cases. I barely found any refrences to this method on the net. The few places which mentioned it, called it: “Dynamic Script Loading”. Therefore, since this is essentially “uncharted territory”, I shall allow myself to give it a more appropriate name myself, one which would also allude to its purpose. I call it: “Dynamic Pseudo-Script Request” or DPSR.
DPSR is basically a utilization of an old JS feature of browsers: The ability to dynamically create a script element on the client-side at runtime. Since <script> elements support external URLs (as their ‘src’ attribute), this opens the door to an endless world of possibilities. <script> elements have the benefit of being able to initiate requests to ANY server as well as executing the response (as long as it conforms to the syntax of javascript, and to be on the safe-side – as long as the content-type is: “text/javascript”). If we could “cheat” the element into running server-side code (which isn’t really a JS file), we could perform any action we want – asynchronously (with parameters in the URL), and even have the ability to dynamically handle the response, if we choose to. The browser doesn’t “care” what happens when it initiates the request, it only cares about the response (of which we have total control).
For example, take the following scenario: We have an online store (http://example.mystore.com), which allows users to add items to their ‘shopping cart’. Now, naturally, we wouldn’t want an action like this (which involves sending data to the server) to have any disruptive effect on the user’s experience. We don’t want to take him anywhere, we don’t want to submit any forms. We just want a simple “call” to be made: http://example.mystore.com/addItem?id=766118. Now, for the sake of this example – let’s assume that this store is insanely popular, and that it’s entirely possible for an item to be sold-out in the time-frame between its presentation to the user – and the user’s action. Also, let’s assume there’s a limit to the number of items any user can purchase.
If we want the user to feel comfortable (and be able to cope with this insane shopping spree), we should allow him to “seamlessly” add items to his cart without affecting anything else on his browser – except for the result of the action itself. This is where DPSR comes in.
<script type=”text/javascript”>
function callBackFunc(status) {
switch(status) {
case 1: break;
case 2:alert(‘item sold-out!’);break;
case 3:alert(‘shopping cart full’);break;
}
}
function addItemToCart(id) {
var newSE = document.createElement(“script”);
newSE.src=”http://example.mystore.com/addItem?id=” + id +”&method=callBackFunc”;
document.body.appendChild(newSE);
}
</script>
<body>
. . .
<a href=”javascript:void(0)” onclick=”addItemToCart(766118)”>Add to shopping cart</a>
. . .
</body>
What happens here is that when we add an item, a script element is planted on the page, with a URL that runs some server-side code. This code returns a javascript response : ” callBackFunc( … ); “. Because the browser was expecting javascript and we gave it what it wants, it would kindfully execute it for us. Simple but ingenious. Granted, this code could be made much more elegant. We could make sure that script elements replace each other rather than be added one after the other ad infinitum; we could make a more user-friendly handler for the result; etc…
The main advantages of XMLHttpRequest over DPSR is support for HTTP headers (when things go wrong and we get 500, 503, 404, etc.), out-of-the-box support for XML responses, the ability to make POST requests, and all the benefits of having a fully functional JS object. DPSR, however, enables a straightforward approach that is cross-domain , cross-browser, and is more light-weight. It’s simple to integrate in your application, and since it’s not an object, we can easily return ANY callback function we want, which gives us a great deal of flexibility.
The main drawback of XMLHttpRequest, in my eyes, is that the flow that results is less intuitive to comprehend and manage. For example, we cannot easily manipulate the VIEW (i.e the page from which we initiated the call) after the response arrives, without hard-coding this behavior into the callback handler. This is not only inflexible, but also creates a dependency between the AJAX logic and the view layer. For example, if we have a re-usable piece of DHTML – such as a registration form, we don’t want our ajax function to “know” about the page we placed that form in. Instead, we want each page to be able to have a different implementation of the callback function, and we want to be able to TELL the server what’s the name of the callback function we want it to use (and wrap the result in).
The main drawback of DPSR, I think, is that it forces you to manipulate the DOM. This, however, is obviously very easy to work around.
| Feature |
XMLHttpRequest |
DPSR |
| HTTP Status |
Supported |
Not Supported |
| Cross-Domain |
Requires server-side workaround |
Supported |
| Cross-Browser |
Requires browser sniffing |
Supported |
| Callback Functionality |
Supported; flow is confusing; unflexible |
Supported; simple flow; flexible |
| XML Response |
Supported |
Requires Handling |
| POST method |
Supported | Not Supported |
| Tidyness | Clean | Messy (DOM manipulation) |
Generally speaking, I think it would be safe to say that XMLHttpRequest is better suited for data retreival, while DPSR serves as an excellent solution for data manipulation (and for very simple calls, such as nickname-availability checks in registration forms).


