Document Domain
January 7, 2011
Every few years I run into an issue with JavaScript-based rich text editors and spellcheckers when they spawn pop-ups. The pop-ups open but don’t function.
If I open my Firebug console in the pop-up, I see something like:
Permission denied for <http://assets2.mysitedomain.com> (document.domain has not been set) to get property Window.tinymce from <http://www.mysitedomain.com> (document.domain has not been set).
Chrome’s console, shows a similar error:
Unsafe JavaScript attempt to access frame with URL http://www.mysitedomain.com/mypage from frame with URL http://assets2.mysitedomain.com/javascripts/lib/tiny_mce/themes/advanced/source_editor.htm. Domains, protocols and ports must match.
In this case, TinyMCE‘s HTML plugin is running-up against JavaScript’s same origin policy because I’m serving assets (and therefore TinyMCE pop-ups) from a different fully-qualified domain name than the page TinyMCE is being embedded in. When not explicitly set, my site’s pages will default to something like www.mysitedomain.com and TinyMCE’s document domain will default to assets2.mysitedomain.com.
The simple fix is to bump up the document domain on my site’s pages to just mysitedomain.com. I do this in my global JavaScript file. I do the same thing to TinyMCE’s tiny_mce_popup.js file.
document.domain = 'mysitedomain.com';
(You might also know that cookies need a similar bump when trying to read and write to them across subdomains.)
Although this works, there is a problem for those developing locally: there’s a good chance they’re not developing at mysitedomain.com but something like localhost. A page at localhost certainly isn’t allowed to claim its document domain is mysitedomain.com.
To handle both cases, we can instead set the document domain smartly, by putting this in both our global JavaScript file and in tiny_mce_popup.js:
document.domain = /(\w+)(.\w+)?$/.exec(location.hostname)[0];
January 13, 2011 at 5:50 pm
yesss thank you so much for this!
January 14, 2011 at 10:42 am
You’re most welcome! I’m glad this article was of some help.
February 15, 2011 at 6:24 am
This helps me too and works for 127.0.0.1.
document.domain = document.domain;
June 9, 2011 at 7:39 pm
looks like an awfully clever workaround, and i hope to try it soon. does this effectively do away with the same origin policy?
June 10, 2011 at 12:24 pm
Thanks. It doesn’t do-away with the same origin policy. The problem is that pages at foo.bar.com and bar.com aren’t of the same origin. This trick just bumps foo.bar.com down to bar.com so that both pages are now of the same origin: bar.com. Does that make sense?