require.js text plugin adds “.js” to the file name

2019-02-16 08:34发布

I'm trying to work with requirejs and text plugin and I have weird problem.

I have two web servers:

  1. localhost:3000 - act as CDN and has all the static files: js, images, css and templates
  2. localhost:3001 - server - act as REST server and serve only one file, the main.html file

The main.html file loads all the js files from the second server using the following line:

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

For some reason, when using the requirejs text plugin, he adds to the templates ".js" suffix when navigating to localhost:3001

I'm using the following syntax:

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

when I navigate to localhost:3000 it works fine.

Can you think of any reason that the text plugin would have problems serving text files from a remote server (for example, CDN server)?

7条回答
【Aperson】
2楼-- · 2019-02-16 08:45

I ran into the same problem and the fix was to make sure the main.js file was loaded from the same domain as the *.htm files. When they differed, require would append the .js to the html files, resulting in 404s.

查看更多
Melony?
3楼-- · 2019-02-16 08:55

I've hacked at every solution I've seen posted on the internet aside from running r.js optimizer and compiling my templates into .js file.

A temporary work around is to put your templates in the same directory as your index.html file. This of course doesn't solve the problem but if you are at a standstill like I was, then this will at least get you moving again.

查看更多
对你真心纯属浪费
4楼-- · 2019-02-16 08:58

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.

查看更多
爷、活的狠高调
5楼-- · 2019-02-16 08:58

I've digged in the code of the text plugin.

I've found out that the text plugin assumes that the developer converted the text template to html since it resides on a different domain.

I've change the code of the text plugin to not assume it.

Someone thinks that I'm doing something wrong?

The original code of the plugin:

            //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);
                });
            }
查看更多
啃猪蹄的小仙女
6楼-- · 2019-02-16 08:59

Such config does not work in current text! plugin. My solution was in overriding useXhr method in 'text' module

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
});
查看更多
来,给爷笑一个
7楼-- · 2019-02-16 09:00

As another alternative way you can use jQuery get method to fetch the content of the template as plain text and then compile it with Handlebars. I came to this solution as a last resort after spending several hours into forums reading about issues with require.js text plugin and CORS. Here's an example :

The template :

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

The js script :

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);

    });

});
查看更多
登录 后发表回答