【问题标题】:Why `init` of shim in my require.js configuration not called?为什么在我的requirejs配置中没有调用shim的`unit`?
【发布时间】:2015-09-05 10:50:22
【问题描述】:

更新

我正在编写一个小模块来处理 backbone 中的这个 csrf 令牌问题,直到我收到@Louis 答案的推送通知。

他的回答非常优雅而且看起来不错,但我会将a link 留给我的 backbone.csrf 模块 github 存储库,供任何需要它的人使用。

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

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

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

由于我使用 require.js 进行模块化 javascript 开发,我尝试在 require.configshim.init 中进行配置,以便在加载 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' 没有被调用。

有什么问题?

【问题讨论】:

    标签: javascript django backbone.js requirejs csrf


    【解决方案1】:

    查看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: {
         '*': {
              backbone: 'backbone-glue'
         },
         'backbone-glue': {
              backbone: 'backbone'
         }
    }
    

    它的作用是,当需要模块 backbone 时,到处 (*) RequireJS 会加载 backbone-glue。但是,在backbone-glue 中,当需要backbone 时,会加载backbone。这允许backbone-glue 加载原始骨干网。

    【讨论】:

      猜你喜欢
      • 2013-03-06
      • 1970-01-01
      • 2014-04-04
      • 2016-12-24
      • 2015-05-25
      • 2014-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多