33

I am working on a CMS site whose domain is:

http://www.acmssite.com

They have a sub-domain where they store a form system:

http://www.forms.acmssite.com

I have an iframe on the first that looks at a form in the latter.

I need to run scripts to manipulate the latter from the former and was wondering is this possible?

p.campbell
  • 98,673
  • 67
  • 256
  • 322
RyanP13
  • 7,413
  • 27
  • 96
  • 166

3 Answers3

78

In order for this to not be restricted by the same origin policy, you will probably need to do this in both the pages:

document.domain = "acmssite.com";
Dark Falcon
  • 43,592
  • 5
  • 83
  • 98
  • 2
    Would this work if both were on completely different domains? – RyanP13 May 18 '11 at 15:34
  • 3
    No. Browsers restrict setting document.domain to the same domain or the superdomain of the web page. For example, here's Mozilla's policy: https://developer.mozilla.org/en/DOM/document.domain – Dark Falcon May 18 '11 at 15:37
  • 5
    Thanks for the tip: placing in both pages. I'd give you a +2 if I could. – Praesagus Oct 16 '12 at 01:41
  • This solution works perfectly for IE7, IE8, IE9, IE10, Firefox, Chrome and Opera, but __doesn't work with the latest IE11__. I have tested it myself with all these browsers using 2 subdomains: www.example.com and iframe.example.com – Both the main page and the iframe contains `document.domain = "example.com";` Seems like a big regression in IE11, please let me know of any workaround thank you! – Community Dec 05 '13 at 19:20
  • 2
    A solution to the above comment ([IE11 bug reported here](http://connect.microsoft.com/IE/feedback/details/807899/ie11-document-domain-can-be-hooked-using-object-defineproperty)) is to place the following meta tag `` just after the doctype declaration. You must use a valid doctype. – Community Dec 12 '13 at 14:01
  • Also make sure they use the same protocol, ie both http or https – Rob Agar Jun 23 '16 at 13:52
  • `document.domain` [is now deprecated](https://developer.mozilla.org/en-US/docs/Web/API/Document/domain). The recommendation is to use postMessage, but my use case is such that postMessage cannot be used. Is there another solution that does not require having to use postMessage? – Ben Davis Nov 05 '20 at 01:36
  • @BenDavis I think you can work around it using `ajax` ... [found this helpful breakdown.](https://docs.jboss.org/exojcr/1.14.4-GA/developer/en-US/html/ch-framework-for-cross-domain-ajax.html) – MeSo2 Nov 18 '22 at 16:51
3

Yes it is.

var iframe = document.getElementById("your-iframes-id").contentWindow.document;
Cobra_Fast
  • 15,671
  • 8
  • 57
  • 102
  • 1
    This code dosn't work when the iframe in subdomain. You need to use "document.domain" – Mosh Feu Mar 11 '14 at 14:24
  • 1
    To clarify what Mosh Feu means: It doesn't work due to same origin policy. The browser with throw "Blocked a frame with origin "null" from accessing a cross-origin frame." – Martin Thoma Sep 12 '17 at 14:47
-1

You can still bypass this issue with the help of YQL even though you don't have access to the header part of the receiving window. With the Postmessage method also you need to edit the recipient window script. But using this method you can load any iframe without touching their scripts. Check this out! jsfiddle-link

<html>
<iframe src="https://google.com/" width="500" height="300"></iframe>

<script>
var iframe = document.getElementsByTagName('iframe')[0];
var url = iframe.src;
var getData = function (data) {
    if (data && data.query && data.query.results && data.query.results.resources && data.query.results.resources.content && data.query.results.resources.status == 200) loadHTML(data.query.results.resources.content);
    else if (data && data.error && data.error.description) loadHTML(data.error.description);
    else loadHTML('Error: Cannot load ' + url);
};
var loadURL = function (src) {
    url = src;
    var script = document.createElement('script');
    script.src = 'https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20data.headers%20where%20url%3D%22' + encodeURIComponent(url) + '%22&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=getData';
    document.body.appendChild(script);
};
var loadHTML = function (html) {
    iframe.src = 'about:blank';
    iframe.contentWindow.document.open();
    iframe.contentWindow.document.write(html.replace(/<head>/i, '<head><base href="' + url + '"><scr' + 'ipt>document.addEventListener("click", function(e) { if(e.target && e.target.nodeName == "A") { e.preventDefault(); parent.loadURL(e.target.href); } });</scr' + 'ipt>'));
    iframe.contentWindow.document.close();
}

loadURL(iframe.src);
</script>
</html>
Gihan Gamage
  • 2,944
  • 19
  • 27