EpicEditor icon indicating copy to clipboard operation
EpicEditor copied to clipboard

setting document.domain breaks IE compatability

Open martin308 opened this issue 11 years ago • 12 comments

Hi, I am having an issue where I need to set document.domain in my page to facilitate cross domain API calls in my JS.

Unfortunately setting this breaks IE compatibility with EpicEditor as the iframe is no longer accessible.

Has anyone dealt with this before?

martin308 avatar Feb 28 '13 01:02 martin308

Do you have a demo? JSBin or something? No one in the issues has ever reported anything like this, but I can take a look.

OscarGodson avatar Feb 28 '13 12:02 OscarGodson

here it is in its most simple form -> http://jsbin.com/olinun/2/edit

The issue is that once document.domain has been set, it must also be set on all iframes. I believe that I know how to fix it.

The code I have been playing with is below

    var hackyHack = "javascript:document.write('<script>document.domain=\"testdomain.com\";</script>')";

    var xIFrame = document.createElement('iframe');
    xIFrame.setAttribute('scrolling', 'no');
    xIFrame.setAttribute('frameborder', '0');
    xIFrame.setAttribute('id', self._instanceId);

    self.element.appendChild(xIFrame);

    xIFrame.src = hackyHack;

    if (xIFrame.attachEvent) {
      xIFrame.attachEvent('onload', function() {
        //run the rest of the initialisation in the load function
      });
    }

This is around line 480, do you think this is the right direction?

martin308 avatar Feb 28 '13 20:02 martin308

I'd put this code in another place not in EpicEditor (thats what you mean by line 480, right?) because in the future if you want to update EpicEditor you'd need to remember to paste this code in again.

That JSBin code you shared doesn't work. You forgot to link EpicEditor :)

From the spec: http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-2250147 It says the property is readonly. I'm curious how this even works and in what browser. What is the use case? Can you just change document.domain and make an AJAX call to any domain? That seems like a serious security risk.

In my tests this doesn't even work: Screen Shot 2013-02-28 at 12 54 14 PM

I'm happy to figure out a way to implement this on my side in the core code, but I'm not sure how this should even works.

OscarGodson avatar Feb 28 '13 20:02 OscarGodson

Yes you can only set it to a valid domain that you are on.

It is used to make ajax calls between subdomains eg. web.amazingapp.com and api.amazingapp.com.

On web.amazingapp.com you set document.domain to 'amazingapp.com' and then api.amazingapp.com has a URL that is placed in an iframe that sets document.domain to 'amazingapp.com' and you can then pipe ajax calls over this bridge. It is fairly common and works in all browsers, it is an alternative to using CORS which is not well supported in IE.

The code is not quite working just yet. It would need to go in epiceditor as it is the one creating the iframes that need to have their document.domain set correctly.

martin308 avatar Feb 28 '13 21:02 martin308

Heres a good blog post that explains the basic concept, probably better than I am! :smiley: http://engineering.foursquare.com/2011/12/08/web-sites-are-clients-too/

martin308 avatar Feb 28 '13 21:02 martin308

Ok I have tweaked the code above a little to work across all browsers correctly.

This is just a proof of concept to see if we have access to the iframe, I have tested in a few browsers now :smiley:

function _getIframeInnards(el) {
    if (el.contentDocument || el.contentWindow.document) {
        alert('hazaah!');
        // we can continue to init the EpicEditor!
    };
}

var element = document.getElementById('epiceditor');

var hackyHack = "javascript:document.write('<script>document.domain=\"epiceditor.dev\";</script>')";

var xIFrame = document.createElement('iframe');
xIFrame.setAttribute('scrolling', 'no');
xIFrame.setAttribute('frameborder', '0');
xIFrame.setAttribute('id', 'iframeIdentifier');
xIFrame.src = hackyHack;

if (window.addEventListener) {
    xIFrame.addEventListener( "load", function(){ _getIframeInnards(xIFrame) }, false );
} else if (window.attachEvent) {
    xIFrame.attachEvent( "onload", function(){ _getIframeInnards(xIFrame) } );
} else {
    xIFrame.onload = function(){ _getIframeInnards(xIFrame) };
}

element.appendChild(xIFrame);

martin308 avatar Feb 28 '13 21:02 martin308

Can you not write the document.domain after the iframe is appended to the DOM?

If not, do you have any suggestions on how we could support this document.domain trick without a developer having to touch the source? Like an option or something?

OscarGodson avatar Feb 28 '13 21:02 OscarGodson

Unfortunately not as once the iframe is written it is unaccsessbile by the parent unless it has that document.domain set.

I am having a go at putting that code into EpicEditor now so hopefully I can demonstrate how it would fit in :+1:

My thoughts were that creating the iframe would be done as above instead of line 486 which uses innerHTML to construct it. The rest of the 'load' function would then have to be done in the callback that is attached by all those load event handlers above as we need to wait for the iframe to finish loading so that it has a chance to execute that script before accessing it. The required domain would need to be passed in on the options so that it can be set to whatever it needs to be.

martin308 avatar Feb 28 '13 21:02 martin308

Awesome :) a pull request would be awesome!!11!1! Don't forget tests.

OscarGodson avatar Feb 28 '13 22:02 OscarGodson

I am still working on this! Having difficulty getting it to work in IE still :-1:

martin308 avatar Mar 11 '13 00:03 martin308

@martin308 Yeah, IE is rough :\

OscarGodson avatar Mar 11 '13 17:03 OscarGodson

Somebody give @OscarGodson some karma for visiting poop.com

toddpi314 avatar Aug 05 '15 09:08 toddpi314