Backbone Sync return an empty $_POST array

2019-04-29 15:01发布

问题:

I'm trying to do my first RESTful app with Backbone and Yii Framework. I had no problem with the GET methods but I'm stuck now with the POST method, to create a new element.

I have a Comment model in Backbone:

var commentModel = Backbone.Model.extend({

    urlRoot: "index.php/api/comments",
    idAttribute: 'id',

    defaults: {
        content: "Empty comment",
        status: 1
    }
});

In my view I add a function to create a new Comment passing the values from the relative form:

on_submit: function(e) {
            var new_comment = new Comment({author_id: this.$('#author_text').val(), content: this.$('#content_text').val(), post_id: this.$("#post_text").val(), status: this.$("#status_text").val()});

         new_comment.save();
        },

Looking the request with Firebug it seems all right, in the POST tab I can see all the values:

JSON            
author_id "7"   
content "Epic fail"
post_id "7" 
status "2"

Source 
{"content":"Epic fail","status":"2","author_id":"7","post_id":"7"}

But in my php Api the $_POST var is empty!

foreach($_POST as $var=>$value) {

     if($model->hasAttribute($var))
        $model->$var = $value;
     else
        $this->_sendResponse(500);
}

Anyone has some ideas? Reading the documentation of Backbone.Sync I understand that it should use POST for create request.

I found a workaround getting the values from:

file_get_contents('php://input') 

but id doesn't feel right to me...

Thanks.

回答1:

From Backbone.sync documentation,

With the default implementation, when Backbone.sync sends up a request to save a model, its attributes will be passed, serialized as JSON, and sent in the HTTP body with content-type application/json.

which means you won't receive data in parameters like in a regular form post but in the body of the HTTP response.

You've got three options to deal with this behavior:

  1. Modify your server code to understand REST requests, see Insert Backbone.js model into MySQL database for example
  2. See if Backbone.emulateJSON could answer your needs
  3. Overwrite Backbone.sync and send the data to better fit your server