PHP not receiving POST body set in Polymer core-ajax element

I’ve created a Polymer element using core-ajax to send data via POST to a PHP script.

<polymer-element name="login-process">
  <template>
    <core-ajax auto method="POST" id="login" url="/login.php" response="{{response}}">
    </core-ajax>
    <button on-tap={{doSend}}>send</button>
  </template>
<script>
Polymer('login-process', {
  ready: function() {
  },
  doSend: function() {
    this.$.login.body = '{"foo": 1, "bar": 2}';
    this.$.login.go();
  },
  responseChanged: function(oldValue) {
      console.log(oldValue);
      console.log(this.response);
  }
})
</script>
</polymer-element>

I’ve examined the HTTP request, and verified the data is being sent. However, my PHP script – on the other hand – is not showing traces of the data in the $_POST or $_REQUEST variables. This is the contents of my PHP script:

Read More
header("Cache-Control: no-cache, must-revalidate"); //HTTP 1.1
header("Pragma: no-cache"); //HTTP 1.0
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past

error_reporting(E_ALL);
ini_set("display_errors", 1);
define("BASE_PATH", $_SERVER['DOCUMENT_ROOT']);

define('WP_USE_THEMES', false);
global $wp, $wp_query, $wp_the_query, $wp_rewrite, $wp_did_header;
require(BASE_PATH . '/wp-load.php');


var_dump($_POST);
var_dump($_REQUEST);

$creds = array();
$creds['user_login'] = 'example';
$creds['user_password'] = 'plaintextpw';
$creds['remember'] = true;
$user = wp_signon( $creds, false );

if ( is_wp_error($user) ) {
    header("HTTP/1.0 401 Unauthorized");
    echo $user->get_error_message();
    exit();
}

header("HTTP/1.0 200 OK");

exit();

Not elegant code, I know. But the response I get from the script is:

array(0) { } array(0) { } ERROR: Invalid username. Lost
your password?

So the $_POST and $_REQUEST arrays are empty, when I’m expecting them to be filled with the data I’ve provided.

Related posts

Leave a Reply

3 comments

  1. in this case you would want to use the “params” attribute this.$.login.params = '{"foo": 1, "bar": 2}'; in place of the “body” attribute. doing so would allow you to get the data with $_POST. the following plunker i used for another answer showing how i create a form in polymer but will also work here to show sending $_POST data to a backend with php. http://plnkr.co/edit/JG7KKbMK0R1Fa1W2Gb4P?p=preview

  2. Here is how I’m using core-ajax to POST some data:

    in the template:

    <core-ajax
            method="POST"
            id="core_ajax_el"
            on-core-response="{{ajax_get_responseHandler}}"
            >
    </core-ajax>
    

    in the prototype:

        domReady: function(e) {
    
        //set AJAX request params: they will be POSTed to the ajax-url.
        var core_ajax_el = this.$.core_ajax_el;
    
        // create the object literal
           var aniArgs = {};
           aniArgs['post_data'] = this.element_attribute;
           core_ajax_el.params = aniArgs;
    
           //set the AJAX URL
             core_ajax_el.url = this.ajax_get_url;
    
           //execute AJAX
             core_ajax_el.go();
    
        },
    
     ajax_get_responseHandler: function(e, detail, sender) {
       //do something with the response here
    
    }
    
  3. So I did some research and made some important findings.

    core-ajax has a property contentType which is by default set to ‘application/x-www-form-urlencoded’.

    The data I was sending was a json object, and it was not url-encoded.

    PHP populates $_POST and $_REQUEST when it contains url-encoded data.
    Further, the data must be in the form of key=value[&key=value…] pairs, as with GET query variables, for the PHP assoc array indices to be instantiated.

    So I could have sent the data with the following code:

    this.$.login.body = 'data='+encodeURIComponent(JSON.stringify({"foo":1, "bar":2}));
    

    now in the PHP script:

    echo $_POST['data'];  // outputs something like string(32) "{"foo":1, "bar":2}"
    
    var $unescaped = stripslashes($_POST['data']);
    
    echo $unescaped; // outputs string(29) "{"foo":1, "bar":2}"
    
    $assoc_array = json_decode($unescaped, true); // now contains an assoc array of the
    // json data
    

    However, I’ve seen people use the following code in their PHP script:

    file_get_contents("php://input");
    

    This gets raw POST data sent to the web server, regardless of whether or not it is url-encoded.

    So, I can just as easily continue sending the data with:

    this.$.login.body = '{"foo": 1, "bar": 2}';
    

    and with PHP have the data set using:

    $data = json_decode( file_get_contents( "php://input", true ) );
    echo $data["foo"]; // outputs 1