0

我想推出 Backbone.js + Require.js。我可以很好地加载模块。但是当我尝试使用文本加载我的 .html 文件时!插件(text.js),我得到这些错误:

资源解释为脚本,但使用 MIME 类型 text/html 传输:“ https://host.net/templates/login.html ”。需要.js:1843

Uncaught SyntaxError: Unexpected token < login.html:1

未捕获的类型错误:无法调用未定义的 underscore.js:1130 的方法“替换”

这是我正在使用的规格:

浏览器:铬

服务器端:带 Slim 的 PHP

机器:带有 bitnami AMI 的 AWS 微实例 // 这些东西附带了生产默认设置,因此 Apache 配置可能不正确,或者 php.ini 不正确。我只是不知道是什么。

目录结构:

/
   dev/    // Webroot: Behind basic_auth for dev reasons
       web/
           index.php    // Starts up the Slim router and PHP backend 
               app/
                   app.html    // The entry point for our SPA, data-main defined here
       js/   // At root for module accessibility in case of reuse
           apps/
           app/
               main.js  // Here we do require.config and bootstrapping
           app.js   
           router.js
           text.js
           modules/
               models/
                   login.js
               views/
                   login.js
           lib/
                   backbone/
                   backbone.js
               jquery/
                   jquery.js
               require/
               require.js
               underscore/
               underscore.js
       templates/   // Also at root for access to reuseable markup, such as login.html
        login.html

这是我认为相关的一些代码:

/js/apps/app/main.js

requirejs.config({
 baseUrl: '/js/apps/app',

  shim: {
    'backbone' : {
      deps: ['underscore', 'jquery'],
      exports: 'Backbone'
    },
    'underscore' : {
      exports: '_'
    },
    'jquery' : {
      exports: '$'
    },
    'backbone.ajaxcommands' : {
      deps : ['backbone', 'underscore', 'jquery'],
    }
  },

  paths: {
    jquery:     'lib/jquery/jquery-1.9.1.min',
    underscore: 'lib/underscore/underscore',
    backbone:   'lib/backbone/backbone-min'
  },

  config: {
    text: {
      useXhr: function (url, protocol, hostname, port)
      {
        protocol = 'https';
  //      return true; 
      }
    }
  }
});
require(['app'],function(App){
    App.initialize(); 
    App.start(); 
  }
); 

/js/apps/app/modules/views/login.js

define([
  'backbone',
  'underscore',
  'modules/views/login',
  'text!/templates/login.html'
], function(Backbone, _, Login, loginTemplate){
  var LoginView = Backbone.View.extend({
    el: $("#login-form"),

    events: {
      "click #login": "login"
    },

    template: _.template(loginTemplate),

    initialize: function(){
      var self = this; 

      this.username = $("#username"); 
      this.password = $("#password"); 

      this.username.change(function(e){
        self.model.set({username: $(e.currentTarget).val()});
      }); 

      this.password.change(function(e){
        self.model.set({password: $(e.currentTarget).val()}); 
      });

    },

    login: function(){
      var user= this.model.get('username'); 
      var pword= this.model.get('password'); 
      if(this.model.save() == false)
      {
        console.log("We got issues loggin' in"); 
      }
      else
      {
        console.log("We should have cookies now"); 
      }
    }

    //render: function(){
    //  this.$el.append(this.template); 
    //}
  });
  return LoginView; 
}); 

/templates/login.html

`<div>hi</div>`

努力寻找解决方案: 当我查看 Chrome 调试器时,在“网络”选项卡下,我看到确实已检索到 login.html,但 chrome 认为它是一个 JS 文件。

我使用断点单步执行代码,发现在 Require.js 1843 中,该行上的节点对象有一个名为“outerHtml”的属性,该属性等于带有一堆属性的“标签”。那么也许它正在将我的 html 包装在标签中?当我查看调试器网络选项卡中的预览选项卡时,我确实看到了标记。如果 login.html 具有有效的 js 代码,那么我不会收到语法错误。我仍然收到 underscore.js 错误,因为它是格式错误的 html。

我已经尝试过这些解决方案: Chrome 说“资源解释为脚本,但使用 MIME 类型文本/纯文本传输。”,给出了什么?

移动项目下的 js/模板代码(使路径相对而不是绝对)。一切似乎都正常,但 text.js 会将 .js 附加到 login.html 的末尾,所以我得到了 404 未找到。这显然是因为跨域访问?

使用 require.config 的各种配置选项,包括设置 baseURL

不幸的是,我忘记了许多其他调整。这真是令人沮丧。

感谢您的时间。

编辑: 我已经放置了一个独立的,它表现出我在我的驱动器上看到的相同行为。文件结构应为:

/
    index.html //This can actually be anywhere visible on the web
    so-js/
        ...
    so-templates/
        ...

请注意,so-js/ 和 so-templates 在 webroot 中,索引文件可以在任何地方。

4

2 回答 2

6

问题是由这一行引起的:

   config: {
    text: {
      useXhr: function (url, protocol, hostname, port)
      {
        protocol = 'https';
      //  return true; 
      }
    }
  }

它覆盖了 text! 的 useXhr 方法,该方法旨在返回一个布尔值以确定文本文件的 Javascript 版本是否可用。如果是,它将返回 false,否则返回 true。

因为您没有返回任何内容并且 undefined 是虚假的,所以这意味着它应该将其加载到 <script> 标记中,这就是您收到 MIME 类型警告和后续错误的原因。

如果删除整个配置属性,错误就会消失,并且 loginTemplate 会填充到 login.html 中。

于 2013-02-20T00:47:42.930 回答
0

您也可以使用grunt从 html 模板生成模块

像这样:

模板/hello.html

<div>hello world!</div>

js/模板/hello.js

define('templates/hello', '<div>hello world!</div>')

咕噜任务配置:

function converTemplate(srcDir){
    return function(){
        grunt.file.recurse(srcDir, function(abspath, rootdir, subdir, filename){
            if(/^.*\.html$/.test(filename)){
                if(subdir){
                    subdir = subdir.replace(/\\/g, '/');
                }

                var content = grunt.file.read(abspath),
                    targetPath = 'js/templates' + '/' + (subdir ? subdir + '/': '') + filename.replace('.html', '.js'),
                    moduleName = 'templates/' + (subdir ? subdir + '/': '') + filename.replace('.html', '');
                content = content.replace(/[ \t]*\r?\n[ \t]*/g, '');
                content = content.replace(/'/g, '\\\'');
                content = "define('"+moduleName+"', [], '"+content+"');";
                subdir && grunt.file.mkdir('js/templates/' + (subdir ? subdir + '/': ''));
                grunt.file.write(targetPath, content);
            }
        });
    };
}

grunt.registerTask('template', 'conver template', converTemplate('templates'));

目录结构:

templates/
    hello.html
js/
    templates/
        hello.js
于 2013-02-20T01:54:01.310 回答