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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RequireJS文本插件:无法从其他域加载HTML相关的知识,希望对你有一定的参考价值。

我想用require.js从另一个域中获取一些html。我知道CORS政策不容易这样做。注意:到目前为止,我已经配置了web服务器(使用Access-Control-Allow-Origin "*"和其他指令)和require.js,所有JS和CSS文件(带有require-css插件的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,但如果它存在与否则没有任何区别。我将?附加到htmlTemplate路径。有了这个,.js没有附加到URL,浏览器加载html内容 - 如前所述,不幸的是,没有require.js将其传递给参数htmlTemplate

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

更新:找到一个解决方案,但如果有人能提供“正确”的解决方案,我会很高兴。

答案

我发现了实际的问题!这部分:

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

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

为了使其工作,有必要在配置部分中使用正确的密钥,因为似乎没有为它评估映射。

所以这是从其他域获取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。另一种选择可能是设置文本的路径。至少必须以某种方式设置配置,以便调用函数...

另一答案

我想我找到了解决方案。 Doc of requirejs/text

因此,如果文本插件确定对资源的请求在另一个域上,它将尝试使用脚本标记访问资源的“.js”版本。跨域允许脚本标记GET请求。 .js版本的资源应该只是一个带有define()调用的脚本,它返回模块值的字符串。

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

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,但由于它是固定模板(即未生成),因此可以接受。

另一答案

我收到No'Access-Control-Allow-Origin'标头出现在请求的资源上。添加代码后

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

以上是关于RequireJS文本插件:无法从其他域加载HTML的主要内容,如果未能解决你的问题,请参考以下文章

RequireJS 模块的定义与加载

RequireJS 订单插件和 Dojo 1.7.1

如何确保Magento 2中的RequireJS在加载其他脚本之前加载jQuery?我发现嵌套需要解决这个问题

使用requireJS的shim参数 解决插件 jquery.ui 等插件问题

无法使用 RequireJs 加载 Dojo 模块

在RequireJS缓存中创建Webpack寄存器模块