10

I'm trying to post data via ajax, this is my info:

    var jsondata =
                {"address" : [
                { "id": addid, "streetaddress": streetaddress, "city": city, "state": state,  "zipcode": zipcode, "latitude": latitude},
            ]   
            };  

    var jsontosend = JSON.stringify(jsondata, null, 2);

ajax function:

    $.ajax({
                type: "POST",
                url: "process.php",
                contentType: "application/json; charset=utf-8",
                dataType: "JSON",
                data: jsontosend,
                success: function(msg){
                   alert(msg);
                          }
             });

            return false;

            alert('Data sent');

}

on the php end, when i print_r($_POST) it just says

    array(0) {
    }

I'm alerting (jsontosend) and its showing me everything perfectly, as well as in firebug using post mothod, its showing all the params sent in a perfect clean manner.

The only way it passes any data is if I use GET method.

Any advice is greatly appreciated!

EDIT: adding POST data from firebug. this is whats being alerted from the alert function:

    {"address":[{"id":1473294,"streetaddress":"3784 Howard Ave","city":"Washington DC","state":"DC","zipcode":20895,"latitude":39.027820587}]}

this is what firebug is showing as whats being passed when using POST method:

    myData=%7B%0A++++%22address%22%3A+%5B%0A++++++++%7B%0A++++++++++++%22id%22%3A+76076%2C%0A++++++++++++%22streetaddress%22%3A+%223784+Howard+Ave%22%2C%0A++++++++++++%22city%22%3A+%22Washington+DC%22%2C%0A++++++++++++%22state%22%3A+%22DC%22%2C%0A++++++++++++%22zipcode%22%3A+20895%2C%0A++++++++++++%22latitude%22%3A+39.027820587%0A++++++++%7D%0A++++%5D%0A%7D

and this is the response for var_dump of $_POST:

    array(0) {

}

this is a var_dump of $_POST['myData']

    NULL
Mike
  • 463
  • 3
  • 8
  • 22

7 Answers7

11

I'm skeptical of the way you're using the contentType property. Try taking out contentType. The default content type is application/x-www-form-urlencoded (http://api.jquery.com/jQuery.ajax/).

Also, use something like {mydata: jsontosend} for your data property.

$.ajax({
            type: "POST",
            url: "process.php",
            //contentType: "application/json; charset=utf-8",
            dataType: "JSON",
            data: {mydata: jsontosend},
            success: function(msg){
               alert(msg);
                      }
         });
Steven Wexler
  • 16,589
  • 8
  • 53
  • 80
  • it was content type! this is a nightmare! – Mike Jan 24 '12 at 07:52
  • 5 hours wasted on this because of something as stupid as content type! it looks terrible still, but I haven't had a chance to add stripslashes yet. – Mike Jan 24 '12 at 07:53
  • Ironically I actually just tried that before I saw your answer and it worked. But your answer is most definitely what it was! Thanks – Mike Jan 24 '12 at 07:54
  • I think you were just fetching it wrong from the php page! Read my comment below – dkulkarni Jan 24 '12 at 07:55
  • @Mike sorry to hear that. Glad you figured it out on your own! – Steven Wexler Jan 24 '12 at 07:57
  • Prefer this answer because contentType seems to be not a strong answer to the problem. http://stackoverflow.com/questions/813487/how-to-post-json-to-php-with-curl – carbontax Aug 31 '12 at 14:43
  • @StevenWexler - This worked for me. Had the same problem with exactly the above contentType +1 – Cyclonecode Oct 12 '16 at 15:10
2

PHP doesn't understand application/json requests (by default). See this question: How to post JSON to PHP with curl

Community
  • 1
  • 1
Jeroen Versteeg
  • 333
  • 2
  • 13
2

I found that the comment provided by dkulkarni was the best solution here. It is necessary to read directly from the input stream to get POST data of any complexity. Changing the value of $.ajax({contentType: ''}) did not work for me..

In order to troubleshoot this problem I had set up a controller method to echo back the JSON I was posting to my server. Changing the ContentType header made no difference. But after reading dkulkarni's comment I changed my server code from this:

    return $_POST;

to this:

    $data = file_get_contents('php://input');
    return json_decode($data);

It worked perfectly.

carbontax
  • 2,164
  • 23
  • 37
  • This is utter genius. THANK YOU!!!! Thanks to dkulkami for the comment, and thanks to you for making the solution more obvious by this answer. I had been at it HOURS trying to work out why $_POST was empty... – kpollock Sep 29 '16 at 13:51
2

Use

data:{myData: jsontosend}

It should send myData as a parameter in your request.

dkulkarni
  • 2,780
  • 4
  • 27
  • 36
  • I've tried, in different combinations, with and without "" around mydata and it still returns an empty array. – Mike Jan 24 '12 at 07:37
  • 2
    Hey have you tried fetching the data from the php input data stream? `` – dkulkarni Jan 24 '12 at 07:51
  • 5
    When you use the JSON content-type, on the PHP side, it's necessary to manually read the JSON string directly from the request body using the php://input stream. – dkulkarni Jan 24 '12 at 07:53
  • I haven't tried that, but removing the content type fixed it. – Mike Jan 24 '12 at 07:56
  • I just tested your method, (copy/pasting your code exactly), it returned null – Mike Jan 24 '12 at 08:00
1

Taking contentType out is not a good idea. You DO want to send this data in JSON format. Key is to do what has been mentioned above, instead of trying to access the data on the receiving end (the target php file) with $data= $_POST it is critical to use $data = file_get_contents('php://input');

Here is an example of the entire round trip for a scenario with php and knockout.js:

JS (on requesting page):

function() {
   var payload = ko.toJSON({ YOUR KNOCKOUT OBJECT });
   jQuery.ajax({
            url: 'target.php',
            type: "POST",
            data: payload,
            datatype: "json",
            processData: false,
            contentType: "application/json; charset=utf-8",
            success: function (result) {
                alert(result);
            }
        });
 };

And then in target.php (the page receiving the request):

$data = file_get_contents('php://input');
$payload_jsonDecoded = json_decode($data
bluegrass
  • 46
  • 4
1

As dkulkarni commented in his post (Jan 24 at 7:53), the only way to retrieve JSON sent with Content-Type application/json seems to be to retrieve it directly from the input stream.

I made a lot of tests with different approaches, but always when I set Content-Type to JSON, the $_POST in PHP is empty.

My problem is I need to set Content-Type to JSON, because the server (where I don't have access) expects it, otherwise it returns unsupported datatype. I suppose they are retrieving directly from input stream.

Why I have to reproduce that in own PHP file? Because I need to make a proxy for testing issues, but thats not the point of this thread.

User
  • 31,811
  • 40
  • 131
  • 232
  • can't you leave datatype: "JSON" and still remove content-type? Thats what I did and it works perfectly. Though it took hours of pulling my hair out before I saw Steven Wexler's answer. – Mike Jan 31 '12 at 02:08
0

Try removing ' dataType: "JSON" ' from the ajax request and check.

Subodh
  • 2,204
  • 18
  • 22