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

时间:2016-07-13 12:37:16

标签: html requirejs cors requirejs-text

我想用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。

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

3 个答案:

答案 0 :(得分:5)

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

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。另一个选项可能是设置文本的路径。至少必须以某种方式设置配置,以便调用函数...

答案 1 :(得分:0)

我想我找到了解决方案。 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,但由于它是固定模板(即未生成),因此可以接受。

答案 2 :(得分:0)

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

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