为什么在我的require.js配置中没有调用`init`的shim?

Jun*_*une 2 javascript django csrf requirejs backbone.js

更新:

我正在写一个小模块来处理骨干中的这个csrf令牌问题,直到我得到@Louis 答案的推送通知.

他的回答相当优雅,看起来很不错,但我会留下一个链接到我的backbone.csrf模块github repo,只为那些需要它的人.

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

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

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

因为我使用require.js进行模块化的javascript开发,所以我尝试配置这个shim.init,require.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>
Run Code Online (Sandbox Code Playgroud)

虽然Backbone已成功加载,但不会调用require配置的'init'.

问题是什么?

Lou*_*uis 6

查看带注释的源代码,我看到Backbone define在检测到它正在运行AMD加载程序时调用.使用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;
});
Run Code Online (Sandbox Code Playgroud)

然后你应该在RequireJS的配置中有这样的地图:

map: {
     '*': {
          backbone: 'backbone-glue'
     },
     'backbone-glue': {
          backbone: 'backbone'
     }
}
Run Code Online (Sandbox Code Playgroud)

这样做的是,*当模块backbone需要时,Anywhere ()需要加载RequireJS backbone-glue.然而,backbone-glue当backbone需要,然后backbone被加载.这允许backbone-glue加载原始Backbone.