jpillora / xdomain

A pure JavaScript CORS alternative
https://jpillora.com/xdomain/
3.12k stars 269 forks source link

Blocked request from master domain. Plus, how to add dynamically? #132

Closed ejbaker closed 9 years ago

ejbaker commented 9 years ago

Can't currently get this to work in either Chrome, Firefox, or IE8+ (emulated through IE11).

Here is the log of activity (obfuscated domains and port):

xdomain (http://subdomain1.example.com): adding slave: http://subdomain2.example.com:3000
xdomain.js:992 xdomain (http://subdomain1.example.com): proxying request to slave: 'http://subdomain2.example.com:3000'
xdomain.js:992 xdomain (http://subdomain1.example.com): creating iframe xdomain-cfdff643
xdomain.js:992 xdomain (http://subdomain1.example.com): new socket: xdomain-ad03cc0e
xdomain.min.js:3 xdomain (http://subdomain2.example.com:3000): blocked request from: 'http://subdomain1.example.com'
xdomain.js:992 xdomain (http://subdomain1.example.com): receive socket: xdomain-ad03cc0e: 'ready'
xdomain.js:992 xdomain (http://subdomain1.example.com): send socket: xdomain-ad03cc0e: request
xdomain.js:992 xdomain (http://subdomain1.example.com): receive socket: xdomain-ad03cc0e: 'XD_CHECK'
xdomain.js:992 xdomain (http://subdomain1.example.com): send socket: xdomain-ad03cc0e: ready
xdomain.js:992 xdomain (http://subdomain1.example.com): ready socket: xdomain-ad03cc0e (emit #1 pending)

Here is my actual code:

subdomain1:

<script src="//cdn.rawgit.com/jpillora/xdomain/0.6.17/dist/xdomain.js" data-slave="http://subdomain2.example.com:3000/static/proxy.html" data-debug="true"></script>

subdomain2:

<script src="//cdn.rawgit.com/jpillora/xdomain/0.6.17/dist/xdomain.js" data-master="http://subdomain1.example.com" data-debug="true"></script>

Additionally: the requirement to put this at the top of the page is an issue for me because I'm working with a template through CMS where I won't have control over the header. I've been trying to add it like so:

(function() {
    try {
        console.log("Working...");
        // create and grab elements
        var script = document.createElement('script');
        var target = document.getElementsByTagName('script')[0];
        // set up script
        script.type = 'text/javascript';
        script.src = 'http://cdn.rawgit.com/jpillora/xdomain/0.6.17/dist/xdomain.js';
        // add custom attributes
        script.setAttribute('data-slave', 'http://subdomain2.example.com:3000/static/proxy.html');
        script.setAttribute('data-debug', 'true');
        // add script to the page
        target.parentNode.insertBefore(script, target);
    }
    catch (e) {
        console.log("Error!", e);
    }
}());

This generates:

Working...
xdomain.js:992 xdomain (http://subdomain1.example.com): adding slave: http://subdomain2.example.com:3000

and then a failed CORS attempt as the browser behaves like the script doesn't exist at all. Here's hoping you have a preferred script for adding this dynamically.

jpillora commented 9 years ago

Some libraries grab the XMLHttpRequest object and store it, so by the time XDomain loads, it's too late. It might be solved by using document write instead of createElement.

Also your requests have to be using exactly the same origin add the slave. Same protocol, host and port.

On Friday, January 16, 2015, ejbaker notifications@github.com wrote:

Can't currently get this to work in either Chrome, Firefox, or IE8+ (emulated through IE11).

Here is the log of activity (obfuscated domains and port):

xdomain (http://subdomain1.example.com): adding slave: http://subdomain2.example.com:3000 xdomain.js:992 xdomain (http://subdomain1.example.com): proxying request to slave: 'http://subdomain2.example.com:3000' xdomain.js:992 xdomain (http://subdomain1.example.com): creating iframe xdomain-cfdff643 xdomain.js:992 xdomain (http://subdomain1.example.com): new socket: xdomain-ad03cc0e xdomain.min.js:3 xdomain (http://subdomain2.example.com:3000): blocked request from: 'http://subdomain1.example.com' xdomain.js:992 xdomain (http://subdomain1.example.com): receive socket: xdomain-ad03cc0e: 'ready' xdomain.js:992 xdomain (http://subdomain1.example.com): send socket: xdomain-ad03cc0e: request xdomain.js:992 xdomain (http://subdomain1.example.com): receive socket: xdomain-ad03cc0e: 'XD_CHECK' xdomain.js:992 xdomain (http://subdomain1.example.com): send socket: xdomain-ad03cc0e: ready xdomain.js:992 xdomain (http://subdomain1.example.com): ready socket: xdomain-ad03cc0e (emit #1 pending)

Here is my actual code:

subdomain1:

subdomain2:

Additionally: the requirement to put this at the top of the page is an issue for me because I'm working with a template through CMS where I won't have control over the header. I've been trying to add it like so:

(function() { try { console.log("Working..."); // create and grab elements var script = document.createElement('script'); var target = document.getElementsByTagName('script')[0]; // set up script script.type = 'text/javascript'; script.src = 'http://cdn.rawgit.com/jpillora/xdomain/0.6.17/dist/xdomain.js'; // add custom attributes script.setAttribute('data-slave', 'http://subdomain2.example.com:3000/static/proxy.html'); script.setAttribute('data-debug', 'true'); // add script to the page target.parentNode.insertBefore(script, target); } catch (e) { console.log("Error!", e); } }());

This generates:

Working... xdomain.js:992 xdomain (http://apsweb.philly.com): adding slave: http://apstest.philly.com:8197

and then a failed CORS attempt as the browser behaves like the script doesn't exist at all. Here's hoping you have a preferred script for adding this dynamically.

— Reply to this email directly or view it on GitHub https://github.com/jpillora/xdomain/issues/132.

jpillora commented 9 years ago

And you can add slaves dynamically with the slaves API, see docs

On Friday, January 16, 2015, ejbaker notifications@github.com wrote:

Can't currently get this to work in either Chrome, Firefox, or IE8+ (emulated through IE11).

Here is the log of activity (obfuscated domains and port):

xdomain (http://subdomain1.example.com): adding slave: http://subdomain2.example.com:3000 xdomain.js:992 xdomain (http://subdomain1.example.com): proxying request to slave: 'http://subdomain2.example.com:3000' xdomain.js:992 xdomain (http://subdomain1.example.com): creating iframe xdomain-cfdff643 xdomain.js:992 xdomain (http://subdomain1.example.com): new socket: xdomain-ad03cc0e xdomain.min.js:3 xdomain (http://subdomain2.example.com:3000): blocked request from: 'http://subdomain1.example.com' xdomain.js:992 xdomain (http://subdomain1.example.com): receive socket: xdomain-ad03cc0e: 'ready' xdomain.js:992 xdomain (http://subdomain1.example.com): send socket: xdomain-ad03cc0e: request xdomain.js:992 xdomain (http://subdomain1.example.com): receive socket: xdomain-ad03cc0e: 'XD_CHECK' xdomain.js:992 xdomain (http://subdomain1.example.com): send socket: xdomain-ad03cc0e: ready xdomain.js:992 xdomain (http://subdomain1.example.com): ready socket: xdomain-ad03cc0e (emit #1 pending)

Here is my actual code:

subdomain1:

subdomain2:

Additionally: the requirement to put this at the top of the page is an issue for me because I'm working with a template through CMS where I won't have control over the header. I've been trying to add it like so:

(function() { try { console.log("Working..."); // create and grab elements var script = document.createElement('script'); var target = document.getElementsByTagName('script')[0]; // set up script script.type = 'text/javascript'; script.src = 'http://cdn.rawgit.com/jpillora/xdomain/0.6.17/dist/xdomain.js'; // add custom attributes script.setAttribute('data-slave', 'http://subdomain2.example.com:3000/static/proxy.html'); script.setAttribute('data-debug', 'true'); // add script to the page target.parentNode.insertBefore(script, target); } catch (e) { console.log("Error!", e); } }());

This generates:

Working... xdomain.js:992 xdomain (http://apsweb.philly.com): adding slave: http://apstest.philly.com:8197

and then a failed CORS attempt as the browser behaves like the script doesn't exist at all. Here's hoping you have a preferred script for adding this dynamically.

— Reply to this email directly or view it on GitHub https://github.com/jpillora/xdomain/issues/132.

ejbaker commented 9 years ago

Hi, thanks for the quick reply!

I'm only using jQuery on the page in question.... but I thought document.write put code down exactly where the document.write statement is. The reason I'm using createElement at all is so that I can move the created script tag to the top of the page's head, which is what I mean by adding things dynamically.

The second comment confuses me. The requests are using exactly the same origin. I forgot to obfuscate one of my URLs, is all; they're all using subdomain2.example.com:3000. Unless I'm misunderstanding your comment?

Thanks again!

jpillora commented 9 years ago

Was on my phone earlier and missed

xdomain.min.js:3 xdomain (http://subdomain2.example.com:3000): blocked request from: 'http://subdomain1.example.com'

from your logs. So it's definitely not a script loading issue we're getting connection logs. This means the slave is failing to parse the master domain.

You could try using the API method instead of script attributes:

 <script src="/dist/xdomain.min.js"></script>
  <script>
    xdomain.debug = true;
    xdomain.masters({
      "http://subdomain1.example.com": "*"
    });
  </script>
ejbaker commented 9 years ago

Looks like the same series:

xdomain (http://subdomain1.example.com): adding slave: http://subdomain2.example.com:3000
xdomain.js:992 xdomain (http://subdomain1.example.com): proxying request to slave: 'http://subdomain2.example.com:3000'
xdomain.js:992 xdomain (http://subdomain1.example.com): creating iframe xdomain-24e3921d
xdomain.js:992 xdomain (http://subdomain1.example.com): new socket: xdomain-b5b8cde
xdomain.min.js:3 xdomain (http://subdomain2.example.com:3000): blocked request from: 'http://subdomain1.example.com'
xdomain.js:992 xdomain (http://subdomain1.example.com): receive socket: xdomain-b5b8cde: 'ready'
xdomain.js:992 xdomain (http://subdomain1.example.com): send socket: xdomain-b5b8cde: request
xdomain.js:992 xdomain (http://subdomain1.example.com): receive socket: xdomain-b5b8cde: 'XD_CHECK'
xdomain.js:992 xdomain (http://subdomain1.example.com): send socket: xdomain-b5b8cde: ready
xdomain.js:992 xdomain (http://subdomain1.example.com): ready socket: xdomain-b5b8cde (emit #1 pending)

Especially of note:

xdomain.min.js:3 xdomain (http://subdomain2.example.com:3000): blocked request from: 'http://subdomain1.example.com'

(I checked this in a Chrome Incognito window to eliminate caching issues.)

I'm using an admittedly slightly-complicated series of functions to talk to an API, but everything works fine with that code when I use CORS. (I'm here for IE8/9 support.)

Here's my slightly convoluted generic send request, for the record. The meat is a jQuery $ajax call. This same function gets called for GET, DELETE, and POST requests on the page.

function sendRequest(type, data, success, error, urlSuffix){
        // don't do anything if user not set
        if (!config.user) {
            return false;
        }
        // get url suffix
        urlSuffix = urlSuffix ? "/" + urlSuffix : "";
        // set up the URL
        var resourceURL = config.domain+':'+config.port+'/api/user/subscriptions' + urlSuffix;

        // handle success and failure
        function apiSuccess(res){
            // success callback, if it exists
            if (success) {
                success(res);
            }
        }
        function apiFailure(res, textStatus){
            // error callback, if it exists
            if (error) {
                error(res);
            }
        }

        $.ajax({
            type: type,
            url: resourceURL,
            data: data,
        })
        // success!
        .done(apiSuccess)
        // failure...
        .fail(apiFailure);
}

I guess the only thing to do now is create a vastly simplified version of the "master" that only GETs, then add complexity in layers until I find the error?

jpillora commented 9 years ago

Does it work in chrome? You could email me a link to a live copy and I try some debugging tomorrow?

On Saturday, January 17, 2015, ejbaker notifications@github.com wrote:

Looks like the same series:

xdomain (http://subdomain1.example.com): adding slave: http://subdomain2.example.com:3000 xdomain.js:992 xdomain (http://subdomain1.example.com): proxying request to slave: 'http://subdomain2.example.com:3000' xdomain.js:992 xdomain (http://subdomain1.example.com): creating iframe xdomain-24e3921d xdomain.js:992 xdomain (http://subdomain1.example.com): new socket: xdomain-b5b8cde xdomain.min.js:3 xdomain (http://subdomain2.example.com:3000): blocked request from: 'http://subdomain1.example.com' xdomain.js:992 xdomain (http://subdomain1.example.com): receive socket: xdomain-b5b8cde: 'ready' xdomain.js:992 xdomain (http://subdomain1.example.com): send socket: xdomain-b5b8cde: request xdomain.js:992 xdomain (http://subdomain1.example.com): receive socket: xdomain-b5b8cde: 'XD_CHECK' xdomain.js:992 xdomain (http://subdomain1.example.com): send socket: xdomain-b5b8cde: ready xdomain.js:992 xdomain (http://subdomain1.example.com): ready socket: xdomain-b5b8cde (emit #1 pending)

Especially of note:

xdomain.min.js:3 xdomain (http://subdomain2.example.com:3000): blocked request from: 'http://subdomain1.example.com'

(I checked this in a Chrome Incognito window to eliminate caching issues.)

I'm using an admittedly slightly-complicated series of functions to talk to an API, but everything works fine with that code when I use CORS. (I'm here for IE8/9 support.)

Here's my slightly convoluted generic send request, for the record. The meat is a jQuery $ajax call. This same function gets called for GET, DELETE, and POST requests on the page.

function sendRequest(type, data, success, error, urlSuffix){ // don't do anything if user not set if (!config.user) { return false; } // get url suffix urlSuffix = urlSuffix ? "/" + urlSuffix : ""; // set up the URL var resourceURL = config.domain+':'+config.port+'/api/user/subscriptions' + urlSuffix;

    // handle success and failure
    function apiSuccess(res){
        // success callback, if it exists
        if (success) {
            success(res);
        }
    }
    function apiFailure(res, textStatus){
        // error callback, if it exists
        if (error) {
            error(res);
        }
    }

    $.ajax({
        type: type,
        url: resourceURL,
        data: data,
    })
    // success!
    .done(apiSuccess)
    // failure...
    .fail(apiFailure);

}

I guess the only thing to do now is create a vastly simplified version of the "master" that only GETs, then add complexity in layers until I find the error?

— Reply to this email directly or view it on GitHub https://github.com/jpillora/xdomain/issues/132#issuecomment-70262313.

ejbaker commented 9 years ago

No, it's not working in Chrome. It isn't working in any browser right now unless I do CORS, bypassing the script totally.

Wow, thanks, that would be great. Let me dig it up.

jpillora commented 9 years ago

Answered on email, problem was your proxy.html file

jpillora commented 9 years ago

Hey @ejbaker looks like my emails are being blocked somehow...


2:40am (2hrs ago)

Strange... I'm now using a different outbound address did you get this one?

See email below


Jan 17 (4 days ago)

Heh, no worries

Found it

http://apstest.*****.com:8197/static/proxy.html

has

<DOCTYPE html>
<script src="//cdn.rawgit.com/jpillora/xdomain/0.6.17/dist/xdomain.min.js"
       data-master="http://abc.example.com"></script>
ejbaker commented 9 years ago

I got this one, but none of the others! Ah well.

On Tue, Jan 20, 2015 at 12:38 PM, Jaime Pillora notifications@github.com wrote:

Hey @ejbaker https://github.com/ejbaker looks like my emails are being

blocked somehow...

2:40am (2hrs ago)

Strange... I'm now using a different outbound address did you get this one?

See email below

Jan 17 (4 days ago)

Heh, no worries

Found it

http://apstest.*****.com:8197/static/proxy.html

has

— Reply to this email directly or view it on GitHub https://github.com/jpillora/xdomain/issues/132#issuecomment-70696914.

Liz Baker

holtjonathan commented 8 years ago

Do you remember what the issue was? I am getting these errors now.

xdomain (https://integrationmdl.grangeinsurance.com): blocked request from: 'https://gainweblifemdl.grangeagent.com'