4

I'm using vanilla JavaScript to send a AJAX post request with JSON data:

xhr.open(method, url,true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify(data));

The headers look good, but in PHP $_POST is empty. There are several related questions on SO about this, like this one, but they all suggest using:

json_decode(file_get_contents("php://input"))

However, if I use jQuery.post my variables end up in $_POST, so it must be possible. My question is how? What might I be doing wrong? Or what could I change?

Community
  • 1
  • 1
Flion
  • 10,468
  • 13
  • 48
  • 68
  • If you want to use `$_POST` then you need to send `application/x-www-form-urlencoded` header, not `application/json`. – dfsq Jan 02 '15 at 18:32
  • I think the best thing to do is to send it as JSON, and use `json_decode(file_get_contents("php://input"))` instead of $_POST. That's really just a preference, but in my opinion, it makes more sense to send JSON because it's much more expressive than $POST variables. – Ruan Mendes Jan 02 '15 at 18:53
  • I might do that for different situations @Juan Mendes, but I'm using the PHP framework Slim which is not picking up my post variables in a $app->post handler if I use json, so that's why I was asking how to get normal $_POST variables and still use json encoding to send data. – Flion Jan 03 '15 at 11:58

1 Answers1

9

That happens because jQuery converts the data you pass in to a string in the format of a form, with a application/x-www-form-urlencoded header, which is something PHP recognizes and correctly creates the $_POST superglobal from.

Your native XMLHttpRequest sends the data as a string in JSON format with the application/json header, which PHP does not recognize as form data, and does not create a $_POST array from.

In modern browsers you can use formData to create valid form data that can be sent with ajax and recognized by PHP

adeneo
  • 312,895
  • 29
  • 395
  • 388
  • I think it would be helpful to explain that the OP is sending the JSON as the body of the HTTP request whereas jQuery is converting the object into `application/x-www-form-urlencoded`, it's not sending JSON – Ruan Mendes Jan 02 '15 at 18:35
  • @adeneo, ah ok! so, I switched back to ```application/x-www-form-urlencoded``` now, and send my data as payload using ```Url.urlEncode(data)```, now I see them in ```$_POST``` however then the objects I try to send end up as the string ```[object Object]```. So should I then ```JSON.stringify``` the individual values of the data I wish to send? – Flion Jan 02 '15 at 18:43
  • @Flion That is correct, right now you're you're sending the result of `Object.toString()` which is called internally because the function requires a string – Ruan Mendes Jan 02 '15 at 18:51