Ajax call with contentType: 'application/json' not working
When using contentType: 'application/json'
you will not be able to rely on $_POST
being populated. $_POST
is only populated for form-encoded content types.
As such, you need to read your data from PHP raw input like this:
$input = file_get_contents('php://input');$object = json_decode($input);
Of course if you want to send application/json
you should actually send JSON, which you are not doing. You either need to build the object serialization to JSON directly, or you need to do something like this - Convert form data to JavaScript object with jQuery - to serialize the object from the form.
Honestly in your case, since you are dealing with form data, I don't quite think the use case for using application/json
is there.
The best practice you refer to is about the server script setting the Content-Type
for JSON to "application/json":
Header('Content-Type: application/json; charset=UTF8');
This is because otherwise a default Content-Type
will be sent, often a catch-all text/html
, and this could lead to an incomprehension with the client.
If you do not specify yourself a Content-Type in the jQuery request, jQuery will determine the most appropriate one. The problem here is that you were sending a POST form, for which the default Content-Type
set by jQuery is application/x-www-form-urlencoded
, which tells PHP to decode the data as POST fields and populate $_POST
. Your script would have then recovered its parameters from $_POST
(or maybe $_REQUEST
).
By changing it to application/json
, $_POST
will no longer be populated, the receiving script operation won't receive the parameters where it was expecting to, and the operation breaks.
So you either need to:
- not specify the Content-Type yourself (better, IMHO)
- set a Content-Type of
application/x-www-form-urlencoded; charset=UTF-8
- set a Content-Type of
application/json; charset=UTF-8
and modify the script to parse the POST stream and decode the JSON data; see this answer.
The third option requires proper handling of php://input
.
The PHP script should be setting the Content-Type header.
if(isset($_POST['ajax']) && $_POST['ajax'] === '1') { header('Content-Type: application/json'); echo json_encode(validateForm($_POST));}