保存模型时如何强制POST请求? [英] How to force a POST request when saving a model?

查看:258
本文介绍了保存模型时如何强制POST请求?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要对服务器端API进行POST。我必须将 id 密钥发送到服务器的请求主体。

I need to make a POST to a server-side API. I must send an id key into the request body to the server.

我使用Backbone模型。但是当我这样做时:

I use a Backbone model. But when I do:

myModel.set("id", somevalue)    
myModel.save()

触发的网络请求是: URL / someValue [PUT]

Backbone不进行POST而是PUT并将id附加到url。

Backbones doesn't do a POST but a PUT and appends the id to the url.

所以我只想在没有Backbone注意的情况下将 id 密钥传递给服务器。

So I just want to pass an id key to the server without Backbone noticing.

推荐答案

来自 Backbone的文档


Backbone已预先配置为与RESTful API同步。

Backbone is pre-configured to sync with a RESTful API.

[...]

默认的 sync 处理程序将CRUD映射到REST,如下所示:

The default sync handler maps CRUD to REST like so:


  • 创建 POST / collection

  • 阅读 GET / collection [/ id]

  • 更新 PUT / collection / id

  • patch PATCH / collection / id

  • 删除 DELETE / collection / id

  • createPOST /collection
  • readGET /collection[/id]
  • updatePUT /collection/id
  • patchPATCH /collection/id
  • deleteDELETE /collection/id

新条目没有ID ,所以如果你在保存之前给模型一个ID,Backbone默认为PUT请求,因为它认为你想保存一个现有的条目。

A new entry doesn't have an ID, so if you give an ID to the model before saving it, Backbone defaults to a PUT request because it thinks you want to save an existing entry.

选择以下解决方案之一。

Choose one of the following solutions.

这个是显而易见的。如果可以,请坚持标准。

更改API以处理PUT / PATCH请求,并仅在创建时使用POST。使API endpoit从URL中获取ID。

Change the API to handle PUT/PATCH requests and only use POST on creation. Make the API endpoit take the ID from the URL.

RESTful API最佳实践

简单且适用于一次性情况。

传递给 save (或 fetch )的每个选项都会覆盖 sync 函数默认定义并传递给 jQuery.ajax 功能

Every options passed to save (or fetch) overrides the options the sync function defines by default and passes to jQuery.ajax function.

Backbone sync source

Backbone sync source


// Make the request, allowing the user to override any Ajax options.
var xhr = options.xhr = Backbone.ajax(_.extend(params, options));




var url = model.url(); // get the url before setting the `id`
model.save({ 
    id: somevalue 
}, { 
    url: url, // fix the url
    type: 'POST' // choose the HTTP verb
});

修复模型使用的网址很简单,你也有一些选择:

Fixing the url that the model uses is simple, you have also some choices:


  • 传递 url 选项(如上所述)

  • 覆盖 url 功能模型的颜色

  • pass the url option (like above)
  • override the url function of the model

覆盖 url 函数( source )适用于每次通话应使用的情况特定网址,没有附加默认 id

Overriding the url function (source) works well for situation where every call should use a specific url, without the default id appended to it.

var MyModel = Backbone.Model.extend({
    url: function() {
        return _.result(this, 'urlRoot') ||
            _.result(this.collection, 'url') ||
            urlError();
    }
});



在模型上设置 idAttribute



这取决于您尝试在数据中传递的 id

Backbone Model使用id具有默认的id属性名称。您可以通过覆盖 idAttribute property <来指定其他名称/ a>模型。无论名称是什么,它总是通过 model.id 属性

Backbone Model uses "id" has the default id attribute name. You can specify a different name by overriding the idAttribute property of the model. Whatever the name, it is always automatically made available through the model.id property.

现在,假设 id 属性与此模型无关并且此模型的真实id属性名称类似于 UID ,您可以更改模型的 idAttribute 以反映真实属性的名称(或者它甚至可以是永远不会成为属性的字符串)。

Now, assuming the id attribute isn't related to this model and this model's real id attribute name is something like UID, you could change the idAttribute of the model to reflect the real name of the attribute (or it could even be a string that's never going to be an attribute).

var MyModel = Backbone.Model.extend({
    idAttribute: 'UID',
});

现在,不考虑 id 属性当前模型的id, model.isNew()将返回 true ,发送POST请求以创建它保存。

Now, the id attribute is not considered an id for the current model, and model.isNew() will return true, sending a POST request to create it on save.

如果你使用的API是 RESTful,你可以通过覆盖 同步功能。这可以在模型或集合上完成,也可以在 Backbone.sync 函数,默认情况下由集合和模型使用。

If the API you're using is not RESTful, you can adjust the behaviors by overriding the sync function. This can be done on the model or collection, or on the Backbone.sync function which is used by default by the collections and models.

例如,如果你想让每个请求默认使用POST为 MyModel class:

For example, if you wanted to make every request use POST by default for MyModel class:

var MyModel = Backbone.Model.extend({
    sync: function(method, model, options) {
        return Backbone.sync.call(this, method, model,
            _.extend({ type: 'POST' }, options));
    }
});

你可以做类似的事情只有保存函数让获取像往常一样执行 GET 请求。

You could do something similar with only the save function to let the fetch do its GET request as usual.


如果您想使用不支持
Backbone的旧版Web服务器默认的REST / HTTP方法,您可以选择打开
Backbone.emulateHTTP 。设置此选项将伪造 PUT PATCH
DELETE 使用HTTP POST 的请求,设置 X-HTTP-Method-Override
标头真正的方法。

If you want to work with a legacy web server that doesn't support Backbone's default REST/HTTP approach, you may choose to turn on Backbone.emulateHTTP. Setting this option will fake PUT, PATCH and DELETE requests with a HTTP POST, setting the X-HTTP-Method-Override header with the true method.

[...]

Backbone.emulateHTTP = true;

model.save();  // POST to "/collection/id", with "_method=PUT" + header.




不要覆盖 isNew



Do not override isNew


此模型是否已保存到服务器了?如果模型还没有
有id,则认为它是新的。

Has this model been saved to the server yet? If the model does not yet have an id, it is considered to be new.

此网站上的其他一些答案建议覆盖 isNew 功能。的不要即可。该函数有其目的并覆盖它以强制POST请求是一个糟糕的黑客,而不是解决方案。

Some other answers on this site suggest overriding the isNew function. Don't. The function has its purpose and overriding it to force a POST request is a poor hack, not a solution.

isNew 在内部使用,但也可以由您的代码或其他库和Backbone插件使用。

isNew is used internally but can also be used by your code or other libraries and Backbone plugins.

1 虽然我没有从堆栈溢出中获取此信息,但它已经AndrésTorresMarroquín对类似问题的回答

1 While I did not take this from stack overflow, it was already an answer by Andrés Torres Marroquín on a similar question.

2 取自 Maanas Royy的回答

2 Taken from Maanas Royy's answer.

这篇关于保存模型时如何强制POST请求?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆