Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

Anybody getting JSON to work with TIdHttp ?

The PHP always return NULL in the $_POST , am I doing anything wrong ?

Delphi source:

http := TIdHttp.Create(nil);
http.HandleRedirects := True;
http.ReadTimeout := 5000;
http.Request.ContentType := 'application/json';
jsonToSend := TStringStream.Create('{"name":"Peter Pan"}');
jsonToSend.Position := 0;
Memo1.Lines.Text := http.Post('http://www.website.com/test.php', jsonToSend);
jsonToSend.free;
http.free;

PHP source:

$value = json_decode($_POST); var_dump($value);

You can't use a TStringList to post JSON data. TIdHTTP.Post() will encode the TStringList contents in a way that breaks the JSON data. You need to put the JSON data into a TStream instead. TIdHTTP.Post() will transmit its contents as-is. Also, don't forget to set the TIdHTTP.Request.ContentType property so the server knows you are posting JSON data.

Your answer was the correct answer, though. To post raw JSON data and have it accepted using the original PHP code, a TStream needs to be used instead of a TStringList, just like you showed. The only error in your answer is you are setting Request.ContentEncoding to UTF-8, which is wrong because UTF-8 is not a valid content encoding. It belongs in Request.CharSet instead. – Remy Lebeau Aug 31, 2012 at 0:01 Remy, I accepted the above becoz it seemed to work, but not sure in the long run. TIdHTTP.Request.ContentType should be to application/json? Also, do you mean I can opt out the json= part? – Atlas Aug 31, 2012 at 4:21 @RemyLebeau, I changed it as you suggested (see code above) using TStringStream. I still get NULL from json_decode($_POST) though. – Atlas Sep 2, 2012 at 11:47 I did a little research and found the original PHP script is wrong in using $_POST in the first place. That only works when posting name/value pairs, which the JSON stream is not. The PHP script needs to use php://input instead to access the raw JSON data, eg: $value = json_decode(file_get_contents('php://input')); – Remy Lebeau Sep 2, 2012 at 17:28

You need to define a post variable, try this code (I have added "json" var to your code):

Delphi code:

http := TIdHttp.Create(nil);
http.HandleRedirects := true;
http.ReadTimeout := 5000;
jsonToSend := TStringList.create;
jsonToSend.Text := 'json={"name":"Peter Pan"}';
Memo1.Lines.Text := http.Post('http://www.website.com/test.php', jsonToSend);
jsonToSend.free;
http.free;

PHP source:

$value = json_decode($_POST['json']); var_dump($value); Have you tried to trace what's going out of your application e.g. using WireShark or similar tools ? I don't know anything about the PHP part, but at least your Delphi part have some issues. – TLama Aug 30, 2012 at 8:30 Seemed the slashes were the culprit, I changed it to $value = stripcslashes($_POST['json']), now working fine – Atlas Aug 30, 2012 at 11:15 @Atlas, try to learn how to use safe try..finally blocks. In your code as well as in this post, the IdHTTP may fail because Indy is driven by exceptions, what may easily cause memory leaks in your application. And anyway, does your code work without change of the request content type ? – TLama Aug 30, 2012 at 12:21 @TLama, yes I will use the try..finally, the source above is just for a simpler view, not the production version. Yes, it seemed to work without ContentType, which was weird... Sometimes Indy drives me crazy... – Atlas Aug 31, 2012 at 4:27

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.