htmlrequirejscorsrequirejs-text

RequireJS text plugin: cannot load HTML from other domain


I'd like to fetch some html from another domain with require.js. I know that CORS policies doesn't allow this easily. Note: I have configured the web server (with Access-Control-Allow-Origin "*" and other directives) and require.js so far that all JS and CSS files (css with require-css plugin) gets loaded from the other domain as expected - just fetching html makes problems. But in the browser network protocol I can see that the html content even gets loaded. However, this content does not get passed to the require function! The browser gets the content, but require.js doesn't provide it as an parameter...

My configuration:

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

Two notes: The useXhr configuration is taken from require.js text plugin adds “.js” to the file name but it makes no difference if it is there or not. I appended a ? to htmlTemplate path. With this the .js does not get appended to the URL and the browser loads the html content - as said before, unfortunately, without that require.js is passing it to parameter htmlTemplate.

What can I do? I've read that if I use the require.js optimizer the generated file wouldn't have this problem anymore (however that works...). But I need to develop my JS without optimization on every edit.

Update: Found one solution but I'd be happy if anyone can provide the 'right' solution.


Solution

  • I've found the actual problem! This part:

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

    should really do it. However, I found out that it wasn't called at all. Instead, the default implementation was called. And this returned false.

    To make it work it is necessary to have the right keys in the config section since the mapping doesn't seem to be evaluated for it.

    So this is the right configuration that fetches HTML from the other domain:

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

    Hallelujah!

    Found the right hint here. Another option might be to set the path for text. At least the configuration must be set somehow so that the function gets called...