我刚开始使用Phil Sturgeon写的休息库。我开始使用它写一些简单的例子。我没有'post'和'get'工作,但不是put和delete。我根据下面的代码提出了一些问题。
// a simple backbone model
var User = Backbone.Model.extend({
urlRoot: '/user',
defaults:{
'name':'John',
'age': 17
}
});
var user1 = new User();
//user1.save(); // request method will be post unless the id attr is specified(put)
//user1.fetch(); // request method will be get unless the id attr is specified
//user1.destroy(); // request method will be Delete with id attr specified
在我的CI REST控制器
中class User extends REST_Controller
{
public function index_get()
{
echo $this->get(null); //I can see the response data
}
public function index_post()
{
echo $this->post(null); //I can see the response data
}
public function index_put()
{
}
public function index_delete()
{
}
}
基本上,当我保存模型或获取模型时,将调用控制器中的get和post。使用模型中指定的id,我可以使用model.save()和model.destroy()向服务器发出put或delete请求。但是,我收到服务器错误。它看起来像无法调用index_put或index_delete。有谁知道我怎么处理:
从git中,我只看到他列出了index_post和index_put。没有index_put和index_delete演示。谁应该帮助我?感谢
答案 0 :(得分:2)
我遇到了同样的问题,看起来浏览器/ html /服务器还没有完全支持DELETE,PUT,PATCH方法。您可能希望查看此堆栈溢出问题:Are the PUT, DELETE, HEAD, etc methods available in most web browsers?
一个简单的解决方案是将骨干线1191的methodMap
更改为以下内容:
// Map from CRUD to HTTP for our default `Backbone.sync` implementation.
var methodMap = {
'create': 'POST',
'update': 'POST', //'PUT',
'patch': 'POST', //'PATCH',
'delete': 'POST', //'DELETE',
'read': 'GET'
};
然后将操作类型包含为模型的属性
var Person = Backbone.Model.extend({
defaults:{
action_type : null,
/*
* rest of the attributes goes here
*/
},
url : 'index.php/person'
});
现在,当您要保存模型时,请执行以下操作
var person = new Person({ action_type: 'create' });
person.set( attribute , value ); // do this for all attributes
person.save();
在application/controllers
文件夹中,您应该有一个名为person.php
的控制器,其类名为Person extends REST_Controller,它具有以下方法:
class Person extends REST_Controller {
function index_get() { /* this method will be invoked by read action */ }
/* the reason those methods are prefixed with underscore is to make them
* private, not invokable by code ignitor router. Also, because delete is
* might be a reserved word
*/
function _create() { /* insert new record */ }
function _update() { /* update existing record */ }
function _delete() { /* delete this record */ }
function _patch () { /* patch this record */ }
function index_post() {
$action_type = $this->post('action_type');
switch($action_type){
case 'create' : $this->_create(); break;
case 'update' : $this->_update(); break;
case 'delete' : $this->_delete(); break;
case 'patch' : $this->_patch(); break;
default:
$this->response( array( 'Action '. $action_type .' not Found' , 404) );
break;
}
}
}
话虽如此,这个解决方案很难看。如果向上滚动骨干实现,您将在第1160行找到以下代码:
// For older servers, emulate HTTP by mimicking the HTTP method with `_method`
// And an `X-HTTP-Method-Override` header.
if (options.emulateHTTP && (type === 'PUT' || type === 'DELETE' || type === 'PATCH')) {
params.type = 'POST';
这意味着您需要设置骨干配置的模拟选项。将以下行添加到main.js
Backbone.emulateHTTP = true;
Backbone.emulateJSON = true;
为了测试它的效果,我创建了一个简单的模型,这里是结果
您需要applications/controllers
文件夹中名为api.php
<?php defined('BASEPATH') OR exit('No direct script access allowed');
require_once APPPATH.'/libraries/REST_Controller.php';
class Api extends REST_Controller
{
function index_get()
{
$this->response(array("GET is invoked"));
}
function index_put()
{
$this->response(array("PUT is invoked"));
}
function index_post()
{
$this->response(array("POST is invoked"));
}
function index_patch()
{
$this->response(array("PATCH is invoked"));
}
function index_delete()
{
$this->response(array("DELETE is invoked"));
}
}
并在js/models
文件夹中创建名为api_model.js
var Api = Backbone.Model.extend({
defaults:{
id: null,
name: null
},
url: "index.php/api/"
});
var api = new Api();
api.fetch({ success: function(r,s) { console.log(s); } }); // GET is invoked
api.save({},{ success: function(r,s) { console.log(s); } }); // POST is invoked
//to make the record old ( api.isNew() = false now )
api.save({id:1},{ success: function(r,s) { console.log(s); } }); // PUT is invoked
api.destroy({ success: function(r,s) { console.log(s); } }); //DELETE is invoked
我不知道怎么做补丁,但希望这有帮助。
修改强>
我发现了如何做补丁,这不包含在代码点火器的REST实现中。在REST_Controller第39行中,您将找到以下内容,
protected $allowed_http_methods = array('get', 'delete', 'post', 'put');
你需要在最后添加'patch'
来接受这个方法,在这之后再添加这段代码
/**
* The arguments for the PATCH request method
*
* @var array
*/
protected $_patch_args = array();
另外,您需要添加以下代码来解析补丁参数:
/**
* Parse PATCH
*/
protected function _parse_patch()
{
// It might be a HTTP body
if ($this->request->format)
{
$this->request->body = file_get_contents('php://input');
}
// If no file type is provided, this is probably just arguments
else
{
parse_str(file_get_contents('php://input'), $this->_patch_args);
}
}
现在,根据骨干文档,您需要传递{patch: true}
来发送PATCH方法,当您调用以下行时,您执行补丁:
api.save({age:20},{patch: true, success: function(r,s) { console.log(s); } });
// PATCH is invoked