Problem with getting JSON from PHP using AJAX

March 3, 2011

I got this problem when I wanted to get back a json produced in PHP. Naturally, I used this header:
header('Content-Type: application/json; charset=utf-8');

It did not work, and that’s the one that everybody said I should use. So I tried different. I tried this:
header('Content-type: text/plain; charset=utf-8');

And it worked! In FireFox, in Chrome, in IE 8 on my computer, but it failed on IE 8 on my co-workers computer. WTF? Yep. Somehow it failed, and it needed a fix.

Since it failed, I can tell you that in AJAX the return value was not the expected one. I used jQuery and expected the dataType: “json” to work. jQuery does the evaluation of the data and creates a JSON object. But not this time. It failed. In IE8 the header seemed to be ignored and the value returned was wrapped in <html><body></body></html> – and yes, it seemed to be a common error somehow, except that none of the solutions mentioned that seemed to work for others worked for me. I even tried some really simple code, and it failed – but I managed to get it to work if the filename actually was .json – but then I could not use PHP. Or could I? The solution was this, with two headers in PHP:

header('Content-type: text/plain; charset=utf-8');
header('Content-Disposition: inline; filename=response.json');

And then do the

echo json_encode($array);

And voila, it worked.


Rebinding in jQuery

August 14, 2010

There is one problem in jQuery that really took a while to figure out(and I’m probably not the first one this happens to), but when I got it – I’ll hopefully never forget it. It’s about ajax part of it, when you have for instance a button with and click event attached to it, and want the same event to be attached to the button returned by ajax. I thought, yea, it should be automatic, but guess what? It was not. The event did not work on the new button added to the page dynamically and I did not get why.

My code was like this:
$(".button").click(function(){
//Do stuff
})

The same as this:
$(".button").bind("click", function(){
//Do stuff
})

The solution was kind of simple, you have to rebind the event to the button that returns from backend. The hard way to do it is to copy the code, or make a method with the code, that is run once the page loads and when the new button arrives to bind it again. But that is just wrong, so I’m glad jQuery had a better answer.

The answer is the .live() method that works exactly the way .bind() does but also in the future:
$(".button").live("click", function(){
//Do stuff
})

I think it’s also possible to use the method .delegate(), where you can delegate the listener to a selector in a specific context like this:
$("body").delegate(".button", "click", function(){
//Do stuff
})