require.js文本插件将“.js”添加到文件名中

时间:2012-05-15 19:18:34

标签: javascript text backbone.js requirejs

我正在尝试使用requirejs和text插件,我有一些奇怪的问题。

我有两个网络服务器:

  1. localhost:3000 - 充当CDN并拥有所有静态文件:js,images,css和templates
  2. localhost:3001 - 服务器 - 充当REST服务器并仅提供一个文件,即main.html文件
  3. main.html文件使用以下行从第二台服务器加载所有 js 文件:

    <script data-main="http://localhost:3000/js/main" 
            src="http://localhost:3000/lib/require-jquery.js"></script>
    

    出于某种原因,当使用 requirejs文本插件时,他在导航到 localhost:3001 时添加了模板".js"后缀

    我使用以下语法:

    define ['jquery','backbone','underscore','models/model','text!templates/main.html', 
            'views/navigation', 'views/player', 'views/content', 'views/header']
    

    当我导航到 localhost:3000 时,它可以正常工作。

    您能想到文本插件在从远程服务器(例如,CDN服务器)提供文本文件时遇到问题的任何原因吗?

7 个答案:

答案 0 :(得分:16)

我在跨域工作时遇到了文本插件的问题,也许你的两个本地主机服务器也遇到了这个问题。

在网络检查员中,我看到 require.js 正在尝试取用some-content.html.js而非some-content.html之类的内容。

您是在开发模式下运行此代码还是构建到生产集中?当您将所有内容捆绑在一起时,文本插件不应该具有相同的跨域麻烦。

以下是API文档部分(从http://requirejs.org/docs/api.html开始):

  

baseUrl可以是不同域上的URL作为页面   加载require.js。 RequireJS脚本加载适用于域。的的   唯一的限制是文本加载的文本内容!插件:那些   路径应与页面位于同一域中,至少在此期间   开发。优化工具将内联文本!插入   资源使用优化工具后,您可以使用资源   那个参考文字!来自其他域的插件资源。

Here's an article帮助我解决了支持CORS的浏览器:

答案 1 :(得分:15)

documentation of the text plugin提供了解决方案的提示:可以通过XHR始终获取远程资源的方式配置插件,而无需附加.js后缀并通过脚本标记加载。简单的解决方案是始终使用XHR强制执行:

requirejs.config({
   config: {
      text: {
         useXhr: function (url, protocol, hostname, port) {
            return true;
         }
      }
   }
});

请注意,远程服务器需要设置正确的CORS标头,这可能是一个安全问题。因此,在使用此方法时,请为可信网址添加必要的检查,而不是简单地返回true

答案 2 :(得分:3)

我已经深入研究了文本插件的代码。

我发现文本插件假设开发人员将文本模板转换为html,因为它位于不同的域中。

我已经将文本插件的代码更改为不承担它。

有人认为我做错了什么?

插件的原始代码:

            //Load the text. Use XHR if possible and in a browser.
            if (!hasLocation || useXhr(url, defaultProtocol, defaultHostName, defaultPort)) {
                text.get(url, function (content) {
                    text.finishLoad(name, parsed.strip, content, onLoad, config);
                });
            } else {
                //Need to fetch the resource across domains. Assume
                //the resource has been optimized into a JS module. Fetch
                //by the module name + extension, but do not include the
                //!strip part to avoid file system issues.
                req([nonStripName], function (content) {
                    text.finishLoad(parsed.moduleName + '.' + parsed.ext,
                                    parsed.strip, content, onLoad, config);
                });
            }

答案 3 :(得分:0)

除了运行r.js优化器并将我的模板编译成.js文件之外,我已经攻击了我在互联网上发布的每个解决方案。

临时解决方法是将模板放在与index.html文件相同的目录中。这当然不能解决问题,但如果你像我一样处于停滞状态,那么这至少会让你再次活动。

答案 4 :(得分:0)

我遇到了同样的问题,修复是为了确保main.js文件是从* .htm文件的同一域加载的。当它们不同时,require会将.js附加到html文件,导致404s。

答案 5 :(得分:0)

这样的配置在当前文本中不起作用!插入。我的解决方案是在文本&#39;中覆盖useXhr方法。模块

require(["text"], function (text)
{   if( location.port == '4502' || location.port == '4503' )// AEM env-t
        text.useXhr = function(){ return true; }
    require(["loader/widget/WidgetLoader"]); // dependent on HTML templates by text! plugin
});

答案 6 :(得分:0)

作为另一种替代方法,您可以使用jQuery get方法以纯文本形式获取模板的内容,然后使用Handlebars对其进行编译。在论坛上花了几个小时阅读有关require.js文本插件和CORS的问题后,我最后才采用了该解决方案。这是一个示例:

模板:

<span class="badge badge-pill badge-danger">Default</span>
<div class="entry">
    <h1>{{title}}</h1>
    <div class="body">
        {{body}}
    </div>
</div>

js脚本:

var deps = [
    'jquery',
    'handlebars',
];

require(deps, function($, handlebars){

    var template = 'https://your_site/raw.templates/basic.handlebars';

    $.get(template, function( data, textStatus, jqxhr ) {
        var Handlebars = handlebars;

        var basicTemplate = Handlebars.compile(data);

        var context = {title: "My New Post", body: "This is my first post!"};

        var html = basicTemplate(context);

        var grid = document.createElement('div');
        grid.setAttribute('id', 'itemsGrid');
        grid.innerHTML = html;
        document.body.appendChild(grid);

    });

});