EpicEditor
EpicEditor copied to clipboard
setting document.domain breaks IE compatability
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?
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.
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?
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:
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.
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.
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/
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);
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?
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.
Awesome :) a pull request would be awesome!!11!1! Don't forget tests.
I am still working on this! Having difficulty getting it to work in IE still :-1:
@martin308 Yeah, IE is rough :\
Somebody give @OscarGodson some karma for visiting poop.com