Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Intercept iframe message nested iframe, cross domain

I have a webpage from domain1.com, there I have an iframe of domain2.com and then I have another iframe inside domain2.com of domain3.com

I want to intercept the messages from domain3.com in domain2.com, If domain2.com isn't inside domain1.com then the messages are received correctly, but if I have domain2.com inside domain1.com then messages from domain3.com are received by domain1.com instead of domain2.com. Is there any way to catch those messages inside domain2.com?

The structure is like this

domain1.com has inside iframe src="domain2.com" domain2.com has inside iframe src="domain3.com"

When I access domain2.com directly it catches domain3.com messages, when I access domain1.com then messages sent from domain3.com are received by domain1.com instead of domain2.com

like image 246
Juan Bayona Beriso Avatar asked Aug 28 '18 13:08

Juan Bayona Beriso


People also ask

How do you communicate between two iframes?

Communicating directly between iframes is also possible by combining window. parent with target as defined above. In conclusion, the postMessage method is a more dynamic alternative to the single DOM, better suited if you load multiple pages in one iframe, but not always easier and it still requires the use of the DOM.

How do I get cross domain iframe content?

To access cross-domain iframe, the best approach is to use Javascript's postMessage() method. This method provides a way to securely pass messages across domains.

How do I find if a click event on a cross domain iframe?

You cannot detect click events in cross-domain iframe. However it's not reliable, loose focus does not mean a click, it could be user moving across the website using TAB .

Can I load an iframe from a different domain?

Generally, web application allows script running between pages(parent and iframe pages) in the same domain based on same-origin-policy. Unfortunately it does not support scripts if different domain. The policy does not allow it.


1 Answers

I tried to recreate your iframe hell. Hopefully, this is what you're looking for. This should cover the scenarios you listed above. Please let me know if I misunderstood anything.

I've also created a Plunker

index.html (domain1)

<!doctype html>
<html>

<head>
  <meta charset="UTF-8">
</head>

<body>
  domain 1

  <form id="form">
    <input type="text" placeholder="Enter message" name="message">
    <input type="submit" value="Click to send">
  </form>

  <iframe src="domain2.html" id="iframe" style="display:block;height:120px"></iframe>

  <script>
    window.addEventListener('message', function(event){
      const [message, domain] = event.data.split('|');
      alert(`domain1: Received ${message} from ${domain}`);
    });

    form.onsubmit = function() {
      iframe.contentWindow.postMessage(`${this.message.value}|domain1`, '*');
      return false;
    };
  </script>

</body>
</html>

domain2.html

<!doctype html>
<html>

<head>
  <meta charset="UTF-8">
</head>

<body>
  domain 2

  <form id="form">
    <input type="text" placeholder="Enter message" name="message">
    <input type="submit" value="Click to send">
  </form>

  <iframe src="domain3.html" id="iframe" style="display:block;height:60px"></iframe>

  <script>
    window.addEventListener('message', function(event){
      const [message, domain] = event.data.split('|');
      alert(`domain2: Received ${message} from ${domain}`);
    });


    form.onsubmit = function() {
      iframe.contentWindow.postMessage(`${this.message.value}|domain2`, '*');
      return false;
    };
  </script>

</body>
</html>

domain3.html

<!doctype html>
<html>

<head>
  <meta charset="UTF-8">
</head>

<body>

  domain 3

  <form id="form">
    <input type="text" placeholder="Enter message" name="message">
    <input type="submit" value="Click to send">
  </form>

  <script>
  window.addEventListener('message', function(event){
      const [message, domain] = event.data.split('|');
      alert(`domain3: Received ${message} from ${domain}`);
    });

    form.onsubmit = function() {
      window.parent.postMessage(`${this.message.value}|domain3`, '*');
      return false;
    };
  </script>

</body>
</html>
like image 117
dysfunc Avatar answered Oct 25 '22 19:10

dysfunc