使用 POST 方法和 Backbone.js 发送数据

Send data using POST method with Backbone.js

我已经使用 Backbone.js 实现了一个简单的登录系统。

我正在尝试使用 HTTP POST 方法将用户名和密码传递给处理用户身份验证的控制器 class。

public function sessions() {
    if ($this->input->server('REQUEST_METHOD') == 'POST') {
        $this->login();
    } elseif ($this->input->server('REQUEST_METHOD') == 'GET') {
        $this->index();
    } elseif ($this->input->server('REQUEST_METHOD') == 'DELETE') {
        $this->session->sess_destroy();
        $this->index();
    }
}

Backbone.js代码段:

$(document).ready(function() {

    var Session = Backbone.Model.extend({
        url: function() {
            var link = "http://<?php echo gethostname(); ?>/reddit/index.php/welcome/sessions";
            return link;
        },
        defaults: {
            username: null,
            password: null
        }
    });

    var model = new Session();

    var DisplayView = Backbone.View.extend({
        el: ".complete",
        model: model,
        type: 'POST',
        initialize: function() {
            this.listenTo(this.model, "sync change", this.gotdata);
        },
        events: {
            "click #signin": "getdata"
        },
        getdata: function(event) {
            event.preventDefault();
            var username = $("input#username").val();
            var password = $("input#password").val();
            this.model.set({ username: username, password: password });
            this.model.fetch();
        },
        gotdata: function() {
            console.log(this.model.get('username'));
            console.log(this.model.get('password'));
            $("#base-nav").load(location.href + " #base-nav");
            $("#signin-form").load(location.href + " #signin-form");
        }
    });

    var displayView = new DisplayView();
});

我目前使用 type 属性来定义 HTTP 方法类型 POST。但这似乎不起作用,因为使用开发人员控制台只能观察到 GET 请求。

必须注意的是,当我删除 event.preventDefault(); 以防止在单击 link (Preventing full page reload on Backbone pushState) 时重新加载页面时,POST 请求似乎已成功传递到后端,尽管页面重新加载阻止了预期的目标行为。

我们如何通过 Backbone.js 使用 POST 请求轻松发送数据?

您正在使用 this.model.fetch(); 来检索数据。它默认发出 GET 请求,并且不在正文或查询字符串中发送任何数据。

尝试查找选项和功能时,使用 documentation. The Backbone source code 也很简短且易于理解。

快速修复

使用保存

this.model.save();

强制执行 POST 请求,就像模型在您已经登录并且只想验证登录时设置了 ìd再次,使用 type 选项 来避免 PUTPATCH 在 Backbone 确定它是更新而不是创建调用时请求。

this.model.save(null, { type: 'POST' });

传递给 save, fetch, create and destroy, all of which use Backbone.sync, are also passed to jQuery's ajax 函数的选项。

现实的解决方案

第一,don't generate JS with PHP.

然后,在Session模型中创建一个函数来处理登录。您甚至可以完全避免 Backbone REST 函数,因为它并不真正适合登录请求的 use-case。

使用模型很有用,因为它提供了通常的 Backbone 事件,并且可以很好地与插件一起使用,例如登录表单视图中的 two-way 绑定。但是调用 savelogin 并不清楚它应该做什么。这就是为什么我们应该为 Session 模型提供明确的 API。

var Session = Backbone.Model.extend({
    urlRoot: "http://example.com/reddit/index.php/welcome/sessions",
    defaults: {
        username: null,
        password: null
    },

    // hide the login complexity inside a function
    login: function(options) {
        // for a really simple login, this would be enough
        return this.save(null, { type: 'POST' });

        // for anything more complex, make a custom call.
        return Backbone.ajax(_.extend({
            url: this.url(),
            method: "POST",
            data: this.attributes,
            dataType: "json",
        }, options));
    },

    // provide other functions for a clear and simple to use API.
    logout: function(){ /*...*/ },
    isAuthenticated: function(){ /*...*/ }
});

然后登录:

var session = new Session();

// in the view
render: function() {
    // caching jQuery object and uses the view's `$` function to scope
    // the search to the view element only.
    this.$username = this.$("input#username");
    this.$password = this.$("input#password");
    return this;
},
getdata: function(){
    session.set({
        username: this.$username.val(),
        password: this.$password.val(),
    });
    session.login({
        context: this,
        success: this.onLoginSuccess
    });
}

我个人使用backbone-session插件将authtoken保存在localStorage中。它提供了开箱即用的好 API 并使用 savefetchlocalStorage.

同步

为什么要自定义 ajax 调用?

Backbone 提供 save 根据 REST 原则将 attributes 与服务器同步,这为 login 服务增加了很多开销不需要 ID 或提出 PUT/PATCH 请求。

你经常会和 Backbone 打架。

更多信息