Cross-Domain Communication with iframes in Classic ASP

Cross-domain communication workaround using nested iframes and query strings

Posted by Hüseyin Sekmenoğlu on June 15, 2010 Full Stack Projects

🎯 Problem

We had two company websites: companyA.com and companyB.com.

On the main page of companyA.com, I created a layout with two iframes and a summary table. Each iframe loads a separate statistics page from each company site. One iframe shows the employee count from Company A and the other from Company B. The goal was to calculate the total number of employees by extracting values from both iframes and displaying them in the summary table on the main page.

This seemed simple at first. I attempted to use JavaScript and document.getElementById() to access values inside the iframes. It worked perfectly for the iframe from companyA.com but failed for the iframe loading from companyB.com. The browser console reported a security error.

After some research, I learned that this is a default browser restriction. JavaScript is not allowed to access content inside iframes that are loaded from a different domain due to cross-origin policy.


🔍 Solution

I searched extensively for a workaround. Many ideas floated around but none were satisfactory until I found a blog post that provided exactly what I needed.

The technique involves a proxy iframe bridge that enables communication between the parent page and the remote domain by creating a loop of requests that end up back in the same domain as the main page.

Here is the flow:

  1. The main page is on companyA.com

  2. It contains an iframe loading a stats page from companyB.com

  3. That stats page on companyB.com contains a hidden iframe that loads a small processing page from companyA.com

  4. Since this last page and the main page are both on companyA.com, JavaScript communication becomes possible

The key trick is that the innermost iframe (hosted again on companyA.com) receives data through a query string and uses JavaScript to call a function on the main page.


🔧 Final Structure

Main Page (companyA.com)

This page contains the summary table and the following JavaScript function:

function processData(company, employeeCount){
  document.getElementById(company).innerHTML = employeeCount;
}

Stats Page (companyB.com)

This is the iframe that the main page loads. When this page finishes loading and calculates its numbers, it injects a hidden iframe with a URL pointing back to companyA.com with parameters included:

function setCompletion(totalEmployees){
  var id = "proxyframe";
  var url = "http://companyA.com/processor.asp?company=companyB&employees=" + totalEmployees;
  var proxy = frames[id];

  if(proxy){
    proxy.location.href = url;
  } else {
    var iframe = document.createElement("iframe");
    iframe.id = id;
    iframe.name = id;
    iframe.src = url;
    iframe.style.display = "none";
    document.body.appendChild(iframe);
  }
}

This ensures a secure roundtrip without triggering cross-origin violations.

processor.asp (companyA.com)

This page is responsible for grabbing the query string values and invoking the function on the parent page:

<%
  company = Request.QueryString("company")
  employees = Request.QueryString("employees")
%>
<script type="text/javascript">
  if(window.top && window.top.processData){
    window.top.processData("<%=company%>", "<%=employees%>");
  }
</script>

✅ Result

With this solution, we managed to fetch employee numbers from both companies and calculate the total safely and effectively.

Today we use this method to pass more than a hundred values across sites. It works flawlessly and keeps both structure and security intact.