peirix
peirix

Reputation: 37771

Two rapid AJAX calls confuses PHP

I just ran into something weird. I have two JSON arrays which holds different data. Usually I just need data from one of them, but when I try to do a dual ajax call to get data from both arrays, I end up with the exact same data on both calls.

Say array 1 holds JSON data on users, and array 2 holds JSON data on houses, and I want to get data from both arrays: (PS! I cut out the url and type to save a couple of lines.)

$.ajax({
   async:false,
   data:"type=users&id=3,5,6",
   success: function(data) {
      data = JSON.parse(data);
      alert(data.length) //will alert 3 as expected
   }
});

Then I make the second call to get some houses in there as well:

$.ajax({
   async:false,
   data:"type=houses&id=2,4",
   success: function(data) {
      data = JSON.parse(data);
      alert(data.length) //alerts 3 as well...
   }
});

When I look at the params and response with Firebug, I can see that the params are correct, but the response is wrong.

In my PHP I even tried to just echo out whatever comes in doing this:

echo $_GET['id'] . ", " . $_GET['type'];

Which made the request look the exact same on both calls... If I put an alert inbetween the ajax calls, I get the expected result (since the system waits). But I thought putting them both to be synchronous would be enough to not crash up the calls..?

edit: I've tried creating a copy of the php file which is called within the AJAX function, and setting the calls to go to seperate files, which makes everything work as expected. So I'm fairly sure there's nothing wrong with the javascript.

more edit: If I remove the parameters from the second AJAX call, I still get the same result. Looking at the request with Firebug I can see that the params list is empty, but the response is still identical...

even more edit: Looking around in Firebug, I can see there is a header called connection which has the value of keep-alive, and then a header called Keep-Alive with the value of 300. I'm guessing this might have something to do with it? Can't find anything on it in the jQuery docs, though...

source code: I've made a small test case, which reproduces the problem:

PHP

echo $_GET['test'];
die();

HTML

<sript>
    $(document).ready(function() {
      $.ajax({
        type:"get",
        url:"bugtest.php",
        data="test=hello",
        success: function(data) {
          $("output").append(data);
        }
      });
      $.ajax({
        type:"get",
        url:"bugtest.php",
        data="test=world!",
        success: function(data) {
          $("output").append(" "+data);
        }
      });
    });
  </script>
  <h1>AJAX bug in Aptana's PHP server?</h1>
  <output></output>

That's all I have, and it does the same thing: Instead of getting hello world! like I'd expect, I get hello hello...

Upvotes: 0

Views: 850

Answers (8)

ChrisR
ChrisR

Reputation: 14457

In order to determine wether PHP or JS is the problem you could use Charles to monitor your request (i trust charles more than firebug actually, dunno why) and generate a unique value serverside

<?php echo uniqid();

If both requests return the same value there is something wrong with your server, else it's the browser or jscode.

Upvotes: 2

Marius
Marius

Reputation: 58959

Try putting the second request in a timeout which waits for 0 seconds.

$.ajax({
   async:false,
   data:"type=users&id=3,5,6",
   success: function(data) {
      data = JSON.parse(data);
      alert(data.length) //will alert 3 as expected
   }
});

setTimeout(function(){$.ajax({
   async:false,
   data:"type=houses&id=2,4",
   success: function(data) {
      data = JSON.parse(data);
      alert(data.length) //alerts 3 as well...
   }
})}, 0);

Upvotes: 0

Scott Saunders
Scott Saunders

Reputation: 30414

Try setting global:false in the jQuery ajax() options.

If that doesn't help, try calling two different PHP pages - one for houses and one for users. If that works, it should at least help narrow the problem down.

Upvotes: 0

Maiku Mori
Maiku Mori

Reputation: 7469

Try using POST.

Also if PHP receives 2 identical requests when they actually aren't supposed to be then it's not PHP's fault; the bug is somewhere between the place where you make the $.ajax call and where web-server passes the request to PHP.

Could you provide some more info about web-server? Which one do you use? Do you have some sort of catching or optimization going on there? Maybe you use some PHP framework or PHP "bootstrap" which could cache request?

You could also try to make a standalone test. Strip the Ajax code out and use minimal php script which just echoes the request. See if you get the same bug.

Some copy-paste data of requests sent and requests received in php would be nice.


I've never seen anything like this, I'm almost sure it's catching related. As a workaround you could just merge both requests in one, you would have to change the PHP script a bit. It's actually probably a better solution as well since you should always try to make as few requests to the server as you can.

Upvotes: 2

Marius
Marius

Reputation: 58959

Put the next ajax call in the response of the first ajax call:

function nextAjaxCall(){
  $.ajax({
    async:false,
    data:"type=houses&id=2,4",
    success: function(data) {
      data = JSON.parse(data);
      alert(data.length) //alerts 3 as well...
    }
  });
}
$.ajax({
  async:false,
  data:"type=users&id=3,5,6",
  success: function(data) {
    data = JSON.parse(data);
    alert(data.length) //will alert 3 as expected
    nextAjaxCall();
  }
  error: function(){
    //error handling
    nextAjaxCall();
  }
});

Make sure that you call the second ajax even if the first one doesn't return successfully.

Upvotes: 0

homelessDevOps
homelessDevOps

Reputation: 20726

Is it possible, that there is some Problem with the data variable ?

What happends if you change your second request to:

$.ajax({
   async:false,
   data:"type=houses&id=2,4",
   success: function(dataHouse) {
      data = JSON.parse(dataHouse);
      alert(dataHouse.length)
   }
});

Upvotes: 0

TigerTiger
TigerTiger

Reputation: 10806

did you try adding timestamp to the URL ?? just to avoid caching etc

 data:"type=houses&id=2,4&"+timestamp

UPDATE:

or just try cache:false in Ajax

You using async:false

Async: 

By default, all requests are sent asynchronous (i.e. this is set to true by default). If you need synchronous requests, set this option to false. Note that synchronous requests may temporarily lock the browser, disabling any actions while the request is active.

may be because of this temporary blocking .. you can try setting it to true.

Upvotes: 5

Boldewyn
Boldewyn

Reputation: 82784

first of all, synchronous AJAX calls are fundamentally bad on a live system. Testing is ok, but don't do this at home, kids! Why? Because if the server doesn't answer in a second or at all (which is quite probable), the browser tab becomes non-responsive. In the worst case (old Mozillas) the whole browser will freeze.

</teaching>

  • Caching should not be the problem, since the URLs are different, when you send GET requests (POSTs are most likely not cached at all).

  • Your alert() test tells you, that it is not PHP's fault, because it sends back all stuff as requested

  • So we remain with JavaScript:

    • If you would've hand-written the code, I'd guess, that you do a wrong check on the request's onreadystate (that is, the function to handle the requested data checks on the wrong request object)

    • Can you tell us, which library you use? Looks like prototype to me.

Cheers,

Upvotes: 6

Related Questions