0

I have searched the internet and stackoverflow topics for an answer but I have not found any. I know JQuery works fine with sending the object but when I try to do the same without the framework, my post is not going through to the PHP page.

My basic 2 basic functions are:

function sendAjax(){
    let car = {type:"Fiat", model:"500", color:"white"};
    var myURL = "ajaxpost.php"; 
    var post_data = {
        myData: car
    };
    ajax(myURL, post_data); 
}

function ajax(url, post_data) {
    var params = typeof data == 'string' ? post_data : Object.keys(post_data).map(
        function(k){ return encodeURIComponent(k) + '=' + encodeURIComponent(post_data[k]) }
    ).join('&');

    var xhr = new XMLHttpRequest();
    xhr.open('POST', url, true);
    xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    xhr.onload = function(){
        if(this.status == 200){
            document.write(this.responseText);
        } 
    }
    xhr.send(params);
}   

My PHP page at ajaxpost.php contains the following

<?php
    $data= $_POST['myData'];
    $results = print_r($data, true);
    echo $results;  // just gives me [object Object]

?>
eric
  • 23
  • 1
  • 4
  • so basicly it's a matter if the `Object.keys(post_data).map().join('$)` returnes what we want – Jeff Jun 01 '18 at 22:22
  • then you'll see that params is `myData=%5Bobject%20Object%5D` – Jeff Jun 01 '18 at 22:25
  • anyway, you cannot post a 2 dimentional object that way. You'll have to serialize it – Jeff Jun 01 '18 at 22:27
  • Are you saying to use JSON.stringify() ? – eric Jun 01 '18 at 22:36
  • No, it would have to be a custom function to get all the sub-objects into one hierarchie. Follow amphetamachine's answer! – Jeff Jun 01 '18 at 22:39
  • or if the data stays as it is you could try to just use `post_data.myData` as param for `Object.keys`. Or just send car to ajax function: `ajax(myURL, car);` and get the properties there as `$_POST['type']` – Jeff Jun 01 '18 at 22:40
  • (Day late, dollar short) How about just change "myData:car" to "myData: JSON.stringify(car)" – dcromley Jun 02 '18 at 02:05

1 Answers1

0

It's because post_data.myData is an object and not a string, that it's being encoded via encodeURIComponent as [Object object].

If you're dead-set on using www/form-data encoding, you will need a function that uses recursion to properly escape all the properties and sub-properties of the complex object.

Far be it from me to suggest using jQuery, but it has a convenience function for just this purpose, $.param(obj).

Otherwise, you could just use JSON:

var jsonString = JSON.encode(complexObject);

Edit: I've since needed to implement this function, so I might as well share it here:

/**
 * Pack up an object of parameters into something that can be added to a GET
 * request.
 *
 * Example:
 * encodeParams({ 'foo': 'bar', 'baz': 'qux' })
 * -> "foo=bar&baz=qux"
 * @param { [key: string]: any } params - key-value store of string->anything
 * @return string URL encoded parameters
 */
var encodeParams = function (params) {
    var up = new URLSearchParams;
    var addParam = function (prefix, param) {
        if (param instanceof Array) {
            for (var _i = 0, param_1 = param; _i < param_1.length; _i++) {
                var i = param_1[_i];
                addParam(prefix + "[]", i);
            }
        }
        else if (param instanceof Object) {
            // add like associative array,
            // e.g. foo[bar][]=baz&foo[bar][]=qux
            for (var i in param) {
                if (param.hasOwnProperty(i)) {
                    addParam(prefix + "[" + i + "]", param[i]);
                }
            }
        }
        else {
            up.append(prefix, (param == null ? '' : param));
        }
    };
    for (var p in params) {
        if (params.hasOwnProperty(p)) {
            addParam(p, params[p]);
        }
    }
    return up.toString();
}; // end encodeParams()
amphetamachine
  • 27,620
  • 12
  • 60
  • 72
  • Well, I'm going to take your advice and go with JQuery. I'll use the jquery builder to just get jquery with ajax which comes to about 50k minified. Thanks for your help. I didn't realize the complexity involved. – eric Jun 01 '18 at 23:00
  • @eric What you could do if you're feeling up to it is re-write [jQuery's .param implementation](https://github.com/jquery/jquery/blob/master/src/serialize.js#L59) to work in vanilla JS. – amphetamachine Jun 04 '18 at 14:03