更新 :

我正在编写一个小模块来处理主干中的这个 csrf token 问题,直到我收到@Louis 回答的推送通知。

他的回答非常优雅,看起来不错,但我会将 a link 留给我的 Backbone.csrf 模块 github repo,仅供需要它的人使用。

================================================== ==================

我使用 Backbone 作为我的前端框架以及我的 Django 后端。

为了与 Django 的 CSRF 保护系统兼容,我必须配置我的 Backbone.sync 以在发送之前为每个 AJAX 请求设置 CSRF 请求 header 。

由于我使用 require.js 进行模块化 javascript 开发,因此我尝试在 shim.initrequire.config 中进行配置,以便在浏览器加载 Backbone 后立即触发此覆盖:

<script>
    var require = {
        ...

        shim: {
            'jquery': {'exports': 'jQuery'},
            'backbone': {
                'deps': ['underscore', 'jquery'],
                'exports': 'Backbone',
                'init': function(_, $) {
                     alert('NOT EVEN CALLED');
                     var originalSync = this.Backbone.sync;
                     this.Backbone.sync = function(method, model, options) {
                         options.beforeSend = function(xhr) {
                             xhr.setRequestHeader('X-CSRFToken', window.csrf_token);
                         }
                         return originalSync(method, model, options);
                     }
                 }
            }
        }
    }
</script>
// Load require.js
<script src="require.js"></script>

尽管 Backbone 已成功加载,但未调用 require 配置的“init”。

问题是什么?

最佳答案

查看 annotated source ,我看到 Backbone 在检测到它正在使用 AMD 加载器运行时调用 define。将 shim 与调用 define 的模块一起使用会导致未定义的行为,因为 shim 用于不调用 define 的模块。

您可以使用像这样的假 backbone 模块来实现您想要的功能,您可以将其保存在名为 backbone-glue.js 的文件中:

define(['backbone'], function (Backbone) {
    var originalSync = Backbone.sync;
    Backbone.sync = function(method, model, options) {
        options.beforeSend = function(xhr) {
            xhr.setRequestHeader('X-CSRFToken', window.csrf_token);
        }
        return originalSync(method, model, options);
    };

    return Backbone;
});

然后你应该在你的 RequireJS 配置中有一个这样的 map :
map: {
     '*': {
          backbone: 'backbone-glue'
     },
     'backbone-glue': {
          backbone: 'backbone'
     }
}

这样做是在任何地方( * )当需要模块 backbone 时 RequireJS 加载 backbone-glue 。但是,在 backbone-glue 中,当需要 backbone 时,会加载 backbone。这允许 backbone-glue 加载原始 Backbone。

关于javascript - 为什么我的 require.js 配置中的 `init` 没有被调用?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30938395/

10-14 15:09