RequireJS text plugin: cannot load HTML from other domain

|▌冷眼眸甩不掉的悲伤 提交于 2020-01-02 15:02:49

问题


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.


回答1:


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...




回答2:


I think I've found a solution. 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.

Because of that I changed the configuration to this, so text is not used anymore:

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

Now http://some.other.domain/test.html.js gets loaded. The content of test.html is:

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

So I surrounded the HTML with a little bit of JS - no problem to me. And now htmlTemplate is set to the expected string. It's not pure HTML anymore, but since it is a fixed template (i.e. not generated) it may be acceptable.




回答3:


I am getting No 'Access-Control-Allow-Origin' header is present on the requested resource. after adding the code

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


来源:https://stackoverflow.com/questions/38351956/requirejs-text-plugin-cannot-load-html-from-other-domain

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!