Forum Moderators: open

Message Too Old, No Replies

Intermittent ajax responses lost

         

lampip

12:30 am on Jun 16, 2007 (gmt 0)

10+ Year Member



I am building a website that uses ajax which allows people to click on items which get added to a list on the screen. You can add, remove, and move items in the list using ajax and everything is working well except for one thing.

Ocassionally (about 1 in 12 actions) the final ajax response does not get back to the client from my server. I put in logic to spit out to a table what it is echo'ing out from my php code for the client and in the cases where the client doesn't get a response i see that it is echo'ing out the right content.

in the javascript in the callback i check the status as follows:
if(xmlHttp.readyState == 4) {
if(xmlHttp.status == 200) {
return 1;
}
}

return 0;

I am also updating a cell on the screen with the status of the ajax object in javascript to see if i get a response of 1 at any point and i don't.

my successful case usually gets 3 '0' values back to the client and the fourth is the final 1 where i can retreive the content. but in these problem cases i get 0's but never the 1.

Has anyone experienced this? Any suggestions?

thanks in advance for any help you can give, in case this is relevant, i am running a web host on a xp machine in my basement and developing on an xp machine in the house, the computers are connected over a wired network in the house.

peter

colandy

7:59 am on Jun 16, 2007 (gmt 0)

10+ Year Member



Only know of 1 other person who experienced similar but that was once every other click.

We will need to see a bit more code, the order of the onReadyStateChange, Open and Send. What your ASP/PHP page does(not the code, just an idea of what it returns to AJAX). What u do with the ASP/ASP Response.

lampip

12:53 pm on Jun 16, 2007 (gmt 0)

10+ Year Member



Thanks for the response, i really appreciate it. Below is the code for the various functions. The behavior is as follows: users browse products on the site and each product has a small icon next to it. User clicks these icons and an ajax call is made to the server where a list of products is kept in their session. the ajax call returns the index location of the added product in the list. javascript then creates a new row element and adds a small product image with an up, down, and remove button below it (the product image name and product id are passed in from the original javascript call).

function createXMLHttpRequest() {
if(xmlHttp) {
if(xmlHttp.readyState > 0 && xmlHttp.readyState < 4) {
return 0;
} else {
xmlHttp.abort();
}
}
if(window.ActiveXObject) {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
} else if(window.XMLHttpRequest) {
xmlHttp = new XMLHttpRequest();
}

return 1;
}

function makeAjaxCall(url, callback) {
if(callback == 'rollover') {
xmlHttp.onreadystatechange = createRolloverCallback;
} else if(callback == 'scratch') {
xmlHttp.onreadystatechange = scratchPadCallback;
} else {
return;
}
url = url + '&ts=' + new Date().getTime();
xmlHttp.open('GET', url, true);
xmlHttp.send(null);
}

function checkAjaxState() {
if(xmlHttp.readyState == 4) {
if(xmlHttp.status == 200) {
return 1;
}
}

return 0;
}

function addScratchPad(productId, imageName) {
currentAction = 'add';
currentProductId = productId;
currentImageName = imageName;

if(createXMLHttpRequest()) {
var url = ajaxDomain + 'misc-pages/scratch-pad-ajax.php?action=add&product_id=' + productId + '&image_name=' + imageName;
makeAjaxCall(url, "scratch");
}

return false;
}

function scratchPadCallback() {
if(checkAjaxState() == 1) {
var xml = getAjaxResponseXml();
var responseText = getInnerText(xml.getElementsByTagName('response').item(0)); // WORKS IN FIREFOX AND IE
if(responseText == 'failure') {
abortAjax();
return;
} else {
switch(currentAction) {
case 'add':
addScratch(xml);
break;
case 'remove':
removeScratch(xml);
break;
case 'up':
upScratch(xml);
break;
case 'down':
downScratch(xml);
break;
}
}
} else {
return;
}
}

Most of the time when a user adds a product it all works fine, but randomly it won't work and the scratchPadCallback will get called three times with checkAjaxState returning 0, but it will never get called with the return value of 1. I know the server side is working because i step through the php and see it adding the product to the list and echo'ing the xml, and if you reload the page the added product appears. The xml returned from the server side is as follows:

<?xml version="1.0" encoding="utf-8"?><response>2</response>

Thank you again for looking at this and i apologize for the very long thread, but i would appreciate any help you could give.

peter

colandy

7:14 pm on Jun 16, 2007 (gmt 0)

10+ Year Member



Try the following code, it's a bit hard to test as we don't have nor want the complete code but try it and let me know.

function ajaxObject(url, callbackFunction)
{
var that=this;
this.updating = false;
this.abort = function()
{
if (that.updating)
{
that.updating = false;
that.AJAX.abort();
that.AJAX=null;
}
}
this.update = function(passData,postMethod)
{
if(that.updating)
{
return false;
}
that.AJAX=null;
if(window.XMLHttpRequest)
{
that.AJAX=new XMLHttpRequest();
}
else
{
var XmlHttpVersions = new Array("MSXML2.XMLHTTP.7.0","MSXML2.XMLHTTP.6.0","MSXML2.XMLHTTP.5.0","MSXML2.XMLHTTP.4.0","MSXML2.XMLHTTP.3.0","MSXML2.XMLHTTP","Microsoft.XMLHTTP");
for (var i=0; i<XmlHttpVersions.length &&!that.AJAX; i++)
{
try
{
that.AJAX=new ActiveXObject(XmlHttpVersions[i]);
}
catch(e)
{
}
}
}
if(that.AJAX==null)
{
return false;
}
else
{
that.AJAX.onreadystatechange = function()
{
if(that.AJAX.readyState==4)
{
that.updating=false;
that.callback(that.AJAX.responseText,that.AJAX.status,that.AJAX.responseXML);
that.AJAX=null;
}
}
that.updating=new Date();
if(/post/i.test(postMethod))
{
var uri=urlCall+'?'+that.updating.getTime();
that.AJAX.open("POST", uri, true);
that.AJAX.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
that.AJAX.setRequestHeader("Content-Length", passData.length);
that.AJAX.send(passData);
}
else
{
var uri=urlCall+'?'+passData+'&timestamp='+(that.updating.getTime());
that.AJAX.open("GET",uri,true);
that.AJAX.send(null);
}
return true;
}
}
var urlCall = url;
this.callback = callbackFunction ¦¦ function() {};
}

function addScratchPad(productId, imageName)
{
currentAction = 'add';
currentProductId = productId;
currentImageName = imageName;
var url = ajaxDomain + 'misc-pages/scratch-pad-ajax.php';
var recObj= new ajaxObject(url, scratchPadCallback);
recObj.update('action=add&product_id=' + productId + '&image_name=' + imageName + '&ts=' + new Date().getTime());
}

function scratchPadCallback(responseText, responseStatus, responseXml) // responseText = echo'd PHP, responseStatus = AJAX Object Status, responseXml = php XML response
{
if(responseStatus == 200)
{
var xml = responseXml();
var responseText = getInnerText(xml.getElementsByTagName('response').item(0)); // WORKS IN FIREFOX AND IE
if(responseText == 'failure')
{
abortAjax();
return;
}
else
{
switch(currentAction)
{
case 'add':
addScratch(xml);
break;
case 'remove':
removeScratch(xml);
break;
case 'up':
upScratch(xml);
break;
case 'down':
downScratch(xml);
break;
}
}
}
else
{
return;
}
}

get rid of the following functions:
createXMLHttpRequest
makeAjaxCall
checkAjaxState

Obviously keep a copy of your original somewhere just in case, the use of the AJAXObject is as follows for future reference:

var recObj= new ajaxObject(page.php', displayData);
recObj.update('opt=1'); //stuff to pass to page.php after the?

function displayData(responseText, responseStatus, responseXml)
{
if(responseStatus==200)
{
//do some stuff with Response Text
}
}

lampip

2:01 am on Jun 17, 2007 (gmt 0)

10+ Year Member



Thank you very much for taking the time to put this together for me, i really appreciate it. i will try this out and let you know how it goes when done, i will probably give it a try tomorrow night (father's day plans tomorrow).

thanks again,
peter

lampip

12:16 am on Jun 21, 2007 (gmt 0)

10+ Year Member



I tried your code and everything worked, but still had the same problem. I wonder if it is just something with my setup at home. I will be pushing this code out to the host we are using soon and will try it there, maybe i won't get the issue.

i noticed with your code you recreate the object everytime and with my code i reused it. Is there a general agreement on which is better? One is faster but does it cause more trouble?

thanks again for your help and will let you know how it goes on the proper host machines.

peter

colandy

7:14 am on Jun 21, 2007 (gmt 0)

10+ Year Member



I can only assume that the issue may be in the ASP/PHP page that the AJAX object calls if the problem is still persisting.

Reused or Recreated object - Don't think it makes much difference, speed should be quicker if you re-use, but then then object variable has to be global. And withthe number of AJAX calls I have in some of my apps, it can get a little hard to keep track.

I use the AJAX Object in a chat application and havn't yet seen any loss in returned data.