15

我正在尝试使用 requirejs 和文本插件,但我遇到了奇怪的问题。

我有两个网络服务器:

  1. localhost:3000 - 充当 CDN 并拥有所有静态文件:js、图像、css 和模板
  2. localhost:3001 - 服务器 - 充当 REST 服务器并仅提供一个文件,即 main.html 文件

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 服务器)提供文本文件时出现问题的任何原因吗?

4

7 回答 7

17

The documentation of the text plugin gives a hint to the solution: It's possible to configure the plugin in a way that it always fetches remote resources via XHR without appending the .js suffix and loading it via script tag. The simple solution is to always enforce using XHR:

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

Note that the remote server needs to set the correct CORS header and that this could be a security issue. Thus add the necessary checks for trusted urls when using this instead of simply returning true.

于 2014-06-26T10:10:42.260 回答
17

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

在网络检查器中,我看到require.js试图获取类似some-content.html.js而不是some-content.html.

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

这是给我提示的 API 文档部分(来自http://requirejs.org/docs/api.html):

baseUrl 可以是与将加载 require.js 的页面不同的域上的 URL。RequireJS 脚本加载跨域工作。唯一的限制是文本加载的文本内容!插件:这些路径应该与页面在同一个域中,至少在开发过程中是这样。优化工具将内联文本!插件资源,所以使用优化工具后,您可以使用引用文本的资源!来自另一个域的插件资源。

这是一篇帮助我为支持CORS的浏览器解决此问题的文章:

于 2012-07-02T13:36:00.280 回答
4

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

我发现文本插件假定开发人员将文本模板转换为 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);
                });
            }
于 2012-05-16T12:22:59.053 回答
0

除了运行 r.js 优化器并将我的模板编译成 .js 文件之外,我已经破解了我在互联网上看到的所有解决方案。

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

于 2012-11-19T21:53:38.527 回答
0

我遇到了同样的问题,解决方法是确保 main.js 文件是从与 *.htm 文件相同的域加载的。当它们不同时,require 会将 .js 附加到 html 文件中,从而导致 404。

于 2013-09-03T17:15:13.077 回答
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);

    });

});
于 2018-12-12T12:07:09.403 回答
0

这样的配置在当前文本中不起作用!插入。我的解决方案是在“文本”模块中覆盖 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
});
于 2017-05-01T17:34:25.943 回答