RequireJS 文本插件:无法从其他域加载 HTML

RequireJS text plugin: cannot load HTML from other domain

我想使用 require.js 从另一个域中获取一些 html。我知道 CORS 政策不允许这样做。注意:我已经配置了 Web 服务器(带有 Access-Control-Allow-Origin "*" and other directives) and require.js so far that all JS and CSS files (css with require-css 插件)按预期从其他域加载 - 只是获取 html 会产生问题。但是在浏览器网络协议中,我可以看到 html 内容甚至被加载了。但是,此内容不会传递给 require 函数!浏览器获取内容,但 require.js 没有将其作为参数提供...

我的配置:

requirejs.config({
    baseUrl: "http://some.other.domain/",
    paths: {
        jquery:       'ext/jquery/jquery.min',
        htmlTemplate: 'test.html?', 
        siteCss:      '../css/site'
    },
    shim: {
        htmlTemplate: [
            'css!siteCss'
        ]
    },

    config: {
        text: {                
            useXhr: function (url, protocol, hostname, port) {
                return true;
            }
        }
    },
    map: {
        '*': {
            text: 'ext/require/text',
            css:  'ext/require/css.min'
        }
    }
});


require(['text!htmlTemplate'], function (htmlTemplate) {
    console.log(htmlTemplate); // prints 'undefined' into the console
});

两个注意事项:useXhr配置取自require.js text plugin adds “.js” to the file name,但是否存在没有区别。我将 ? 添加到 html 模板路径。有了这个 .js 不会附加到 URL 并且浏览器加载 html 内容 - 如前所述,不幸的是,没有 require.js 将它传递给参数 htmlTemplate.

我能做什么?我读过如果我使用 require.js optimizer 生成的文件将不再有这个问题(但是它有效......)。但是我需要在每次编辑时都没有优化的情况下开发我的 JS。

更新:找到了一个解决方案,但如果有人能提供 'right' 解决方案,我会很高兴。

我想我找到了解决办法。 Doc of requirejs/text:

So if the text plugin determines that the request for the resource is on another domain, it will try to access a ".js" version of the resource by using a script tag. Script tag GET requests are allowed across domains. The .js version of the resource should just be a script with a define() call in it that returns a string for the module value.

因此我将配置更改为此,因此不再使用文本:

requirejs.config({
    baseUrl: "http://some.other.domain/",
    paths:   {
        jquery:       'ext/jquery/jquery.min',
        htmlTemplate: 'test.html', // removed the '?'
        siteCss:      '../css/site'
    },
    shim:    {
        htmlTemplate: [
            'css!siteCss'
        ]
    },
    map:     {
        '*': {
            // removed the text plugin
            css:  'ext/require/css.min'
        }
    }
    // removed the useXhr configuration for the text plugin
});


require(['htmlTemplate'], function (htmlTemplate) {
    console.log(htmlTemplate); // prints '<div>Here I am!</div>' into the console
});

现在 http://some.other.domain/test.html.js 已加载。 test.html的内容是:

define(function () {
    return '<div>Here I am!</div>';
});

所以我用一点 JS 包围了 HTML - 对我来说没问题。现在 htmlTemplate 设置为预期的字符串。它不再是纯粹的 HTML,但由于它是固定模板(即未生成),因此可能是可以接受的。

我找到了真正的问题!这部分:

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

真的应该这样做。但是,我发现它根本没有被调用。相反,调用了默认实现。这返回了 false。

要使其正常工作,必须在配置部分中使用正确的键,因为似乎没有针对它评估映射。

所以这是从其他域获取 HTML 的正确配置:

requirejs.config({
    baseUrl: "http://some.other.domain/",
    paths: {
        jquery:       'ext/jquery/jquery.min',
        htmlTemplate: 'test.html', //                     // ---> removed the '?'
        siteCss:      '../css/site'
    },
    shim: {
        htmlTemplate: [
            'css!siteCss'
        ]
    },

    config: {
        'ext/require/text': {                              // ---> full path is required!!!               
            useXhr: function (url, protocol, hostname, port) {
                return true;
            }
        }
    },
    map: {
        '*': {
            text: 'ext/require/text',
            css:  'ext/require/css.min'
        }
    }
});


require(['text!htmlTemplate'], function (htmlTemplate) {
    console.log(htmlTemplate);   // now prints HTML into the console!!!
});

哈利路亚!

找到正确的提示here。另一种选择可能是为 text 设置路径。至少必须以某种方式设置配置,以便调用该函数...

我收到请求的资源上没有 'Access-Control-Allow-Origin' header。添加代码后

config: {
        'ext/require/text': {                             // required!!!               
            useXhr: function (url, protocol, hostname, port) {
                return true;
            }
        }
    },