So one caveat with AJAX is the fact that you cannot AJAX files. At SolutionSet we adopted a solution called an iframe proxy or as Grady Khunline would call it "FAJAX". It involves injecting an iframe in the document and setting a form to target that iframe whenever it is submitted. Using a proxy has another advantage over AJAX in that we can also retrieve data accross servers and is a native solution where AJAX is unavailable. One main caveat when using an iframe proxy is that you cannot get response headers which depending on your project may or may not be important.
I found that when dealing with browsers there is infact a specific way to implement this. Before I go into details an example can be found at
http://projects.blanquera.com/proxy/ . It has been tested in IE6+7, FF2+3, Safari, Opera and Google Chrome. The general solution I will provide will be explained using native JavaScript.
1. Create an iframe.
var frame = document.createElement('div');
frame.innerHTML = '<iframe id="frame_proxy" name="frame_proxy" src="blank.html"></iframe>';
frame = frame.getElementsByTagName('iframe')[0];
frame.style.display = 'none';What this does is create an iframe wrapper and set the innerHTML to a string version of an iframe. In IE6+7, creating an iframe using the DOM builder (document.createElement) does not correctly register the iframe to
windows.frames. Setting an innerHTML however does. Pretty wierd. The last valuable thing about this is
src="blank.html". FF3, Safari, Opera and Google Chrome require this to be set for
frame.onload to work properly. At this point there are 2 paths you can take.
2. Change target of an existing form to the id of the iframe.
document.getElementById('myFormId').setAttribute('target', 'frame_proxy')Cross browser this should work. If you do not have a form and wish to just manually post to a page you will need to create a form dynamically. Don't fret, here's the implementation.
var form = document.createElement('form');
form.setAttribute('method', 'post');
form.setAttribute('action', 'server.php');
form.setAttribute('target', 'frame_proxy');
var params = unserialize('name=Joe&age=24');
for(var key in params)
{
input = document.createElement('input');
input.setAttribute('type', 'hidden');
input.setAttribute('name', key);
input.setAttribute('value', params[key]);
form.appendChild(input);
}So what I'm trying to accomplish is convert a serialized set of parameters into a set of hidden fields. To do this we must first convert that string into a parsable object. I use my handy
unserialize() function to accomplish this. From this code you can probally figure out how to make it dynamic for your project.
function unserialize(serial) {
var keyValue, unserial = {};
serial = serial.split('&');
for(var i = 0, length = serial.length; i < length; i++)
{
keyValue = serial[i].split('=');
if(keyValue.length == 2)
{
unserial[keyValue[0]] = keyValue[1];
}
}
return unserial;
};3. Listen to iframe onload
frame.onload = function() {
var response = frame.contentWindow.document.body.innerHTML;
//////////////
//Do something with the response
//////////////
frame.parentNode.removeChild(frame);
}This would be the area you would add your custom functionality in. Across all browsers,
frame.contentWindow.document.body.innerHTML is the perferred way to get the contents of an iframe and it does not matter if the result is in HTML or not this way will still get the raw data. The last part of this is removing the iframe and possible the form from the document however you want. If you dynamically created the form from the last step you want add
form.parentNode.removeChild(form); below
frame.parentNode.removeChild(frame);4. Add the frame to the document
document.body.appendChild(frame);
If you dynamically created the form from step 2 then you also want to invoke
form.submit(); after this. It's important to know that you can use the same iframe for every proxy call however in jQuery, do not use
$(document.body).append(iframe); because this will first clone the iframe then append it. You will find yourself with multiple iframes in your document.
The example at
http://projects.blanquera.com/proxy/ is written in jQuery. I called my plugin "proxy". Here's how you would use it:
$.proxy({
url: 'server.php',
form: form,
success: function(response) {
form.replaceWith('<div>'+response+'</div>');
}
});I hope this was informative. If you have any questions please comment and I will get back to you as soon as possible. Enjoy!