我想推出Backbone.js + Require.js。我可以加载模块就好了。但是当我尝试使用文本加载我的.html文件时!插件(text.js),我收到这些错误:
资源解释为脚本,但使用MIME类型text / html传输:“https://host.net/templates/login.html”。 require.js:1843
未捕获的SyntaxError:意外的令牌<的login.html:1
未捕获的TypeError:无法调用undefined underscore.js的方法'replace':1130
以下是我正在使用的规范:
浏览器 :Chrome
服务器端 :PHP w / Slim
计算机 :带有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 says "Resource interpreted as script but transferred with MIME type text/plain.", what gives?
在项目下移动js /模板代码(使路径相对而不是绝对)。一切似乎都有效,但text.js会将.js附加到login.html的末尾,所以我找不到404。这是因为跨域访问是偶然的?
使用require.config的各种配置选项,包括设置baseURL
不幸的是,我遗忘了许多其他的调整。这真是令人沮丧。感谢您的时间。
修改 我把一个独立的东西展现出我在drive上看到的相同的行为。文件结构应为:
/
index.html //This can actually be anywhere visible on the web
so-js/
...
so-templates/
...
注意so-js /和so-templates是在webroot上,索引文件可以在任何地方。
答案 0 :(得分:6)
问题是由这一行引起的:
config: {
text: {
useXhr: function (url, protocol, hostname, port)
{
protocol = 'https';
// return true;
}
}
}
它覆盖了文本!的useXhr方法,它意味着返回一个布尔值来确定文本文件的Javascript版本是否可用。如果是,它将返回false,否则为true。
因为你没有返回任何内容并且undefined是假的,所以它需要意味着它应该在&lt; script&gt;中加载它。标记,这就是为什么你得到MIME类型警告和后续错误。
如果删除整个配置属性,则错误消失,loginCMmplate将填入login.html。
答案 1 :(得分:0)
您也可以使用grunt从html模板生成模块
像这样:模板/ hello.html的
<div>hello world!</div>
到
JS /模板/ hello.js
define('templates/hello', '<div>hello world!</div>')
grunt任务配置:
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