I use my own custom AJAX library (I m not interested in using jQuery, etc.), which is working flawlessly in the following browsers:
- Firefox 7
- Chrome 14
- IE 8
- IE 8 (compatibility mode)
Using my custom AJAX library in the aforementioned browsers, I can make as many AJAX requests as I want, in any order, using GET and/or POST methods, and they all work flawlessly. Since a new AJAX object is created for every request (see code below), I can even have more than one AJAX request process simultaneously with success.
However, in Safari 5 an AJAX POST request only passes POST data to the server if it is the absolute first AJAX request to execute. Even if I execute the exact same AJAX POST request twice in a row, the POST data is only passed to the server during the first request. Here is the JavaScript in my custom AJAX library:
if (!Array.indexOf) { Array.prototype.indexOf = function(obj) { for (var i = 0; i < this.length; i++) { if (this[i] == obj) { return i; } } return -1; }; } function ajaxObject() { if (window.ActiveXObject) { var activexmodes = ["Msxml2.XMLHTTP", "Microsoft.XMLHTTP"]; for (var i = 0; i < activexmodes.length; i++) { try { return new ActiveXObject(activexmodes[i]); } catch (e) { } } } else if (window.XMLHttpRequest) { return new XMLHttpRequest(); } else { return false; } } function ajaxRequest(aURI, aContainerId, aPostData, aResponseType, aAvoidBrowserCache) { // Initialize var xmlhttp = new ajaxObject(); xmlhttp.onreadystatechange = function() { if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { if (aResponseType != "eval" && aResponseType != "EVAL") { // Show HTML for response document.getElementById(aContainerId).innerHTML = xmlhttp.responseText; } else { // Parse & execute JavaScript for response var responseText = xmlhttp.responseText; var startPos, endPos; for (var i = 0; i < responseText.length; i++) { if (responseText.substring(i, i + 6) == "<eval>") { startPos = i + 6; break; } } for (var i = startPos; i < responseText.length; i++) { if (responseText.substring(i, i + 7) == "</eval>") { endPos = i; break; } } textToEval = responseText.substring(startPos, endPos); eval(textToEval); } } else { try { if (xmlhttp.status != 0 && xmlhttp.status != 200) { alert( Error + xmlhttp.status); } } catch (e) { // Handle IE8 debug "unknown error" } } } if (aAvoidBrowserCache != false) { // Combat browser caching: aURI = aURI + (aURI.indexOf("?") == -1 ? "?" : "&"); theTime = new Date().getTime(); aURI = aURI + theTime + "=" + theTime; } // Make request if (typeof aPostData == "undefined" || aPostData == null || aPostData == "") { // GET request xmlhttp.open("GET", aURI, true); xmlhttp.send(); } else { // POST request var parameters = ""; if (aPostData.constructor.toString().indexOf("Array") != -1) { // Use parameters passed as array for (var postCount = 0; postCount < aPostData.length; postCount++) { if (parameters != "") { parameters = parameters + "&"; } parameters = parameters + aPostData[postCount][0] + "=" + encodeURIComponent(aPostData[postCount][1]); } } else { // Use parameters passed as string parameters = aPostData; } xmlhttp.open("POST", aURI, true); xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); xmlhttp.send(parameters); } }
So for example, either of the following AJAX POST requests will pass POST data if they are the absolute first AJAX request (whether GET or POST); otherwise, the POST data is not passed:
ajaxRequest("test.aspx", "", [["name1","value1"],["name2","value2"]], "eval");
or
ajaxRequest("test.aspx", "", "name1=value1&name2=value2", "eval");
I have added debug statements all throughout my AJAX library, and the POST parameters are being created in the "parameters" variable as expected prior to each POST request. I have absolutely no idea why, only in Safari 5 (out of the mentioned browsers), I have this problem. Any ideas?
Thanks in advance! Jesse