2

我想用 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 文本插件在文件名中添加“.js”,但是否存在没有区别。我?在 htmlTemplate 路径中附加了一个。这样,.js不会将其附加到 URL 并且浏览器会加载 html 内容 - 如前所述,不幸的是,没有 require.js 会将其传递给 parameter htmlTemplate

我能做些什么?我已经读过,如果我使用require.js 优化器,生成的文件就不会再出现这个问题了(但是它可以工作......)。但是我需要开发我的 JS 而不对每次编辑进行优化。

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

4

3 回答 3

6

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

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

哈利路亚!

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

于 2016-07-14T08:21:33.913 回答
0

我想我找到了解决办法。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,但由于它是一个固定模板(即未生成),它可能是可以接受的。

于 2016-07-13T13:01:13.367 回答
0

我收到请求的资源上没有“Access-Control-Allow-Origin”标头。添加代码后

config: {
        'ext/require/text': {                             // required!!!               
            useXhr: function (url, protocol, hostname, port) {
                return true;
            }
        }
    },
于 2017-01-21T05:22:39.430 回答