How to call a JavaScript function of parent Visualforce page from iframe

Whenever there is cross domain and we try to call any JavaScript function of parent Visualforce page from an iframe included in the same page, with window.parent, we get the below error:
Uncaught DOMException: Blocked a frame with origin "---" from accessing a cross-origin frame.
  • What is cross domain :- Cross domain means that the main page is running on a different domain, for example like "https://c.ap16.visual.force.com/" and the link in the iframe src has different domain like "https://sfdciframeexample.herokuapp.com/". And for security reasons cross domain javascript call is restricted by browser itself.

Example:
Here I have created a Vf page and included a iframe in it and both has different domain, my vf page is running on "https://c.ap16.visual.force.com/" and my iframe src has a link of a page which is hosted on heroku "https://sfdciframeexample.herokuapp.com/".

My VisualForce Page:
<apex:page showheader="false" sidebar="false">
  
  <style>
      body{
          background-color: yellow;
      }
  </style>
  
  <script>
      function mainPageFunction(){
          
          alert('mainPageFunction called');
      }   
      
      
  </script>
<div style="margin-left: 20px;">
<h1 style="font-size: 40px;">
This is my main page</h1>
</div>
</apex:page>

My HerokuApp Page:

<html>
<head>
  <script type="text/javascript">
    
    function callParentFunction(){

        window.parent.mainPageFunction();
    }

  </script>
</head>

<body>


<div class="jumbotron text-center">
  <div class="container">
    
    <h1>
This is a sample app delpoyed on heroku</h1>
</div>
</div>
<div class="container">
    <button onclick="callParentFunction();">Call Parent function</button>
  
  
</div>
</body>
</html>

Now if I want to call this JavaScript method "mainPageFunction()" from the page which is hosted on heroku, and if I use "window.parent.mainPageFunction();". I will get the error which I mentioned above and hence it will not work.



Solution: MessageEvent postMessage method.
We have to use "postMessage" method and will pass a message to parent window which will tell the parent window to call the required JavaScript method.

Example:
First yo have change your Vf page JavaScript method a bit to accept the "event" param, something like below:
function mainPageFunction(event){
   if (event.data && event.data.action) {
      if (event.data.action == 'callparent') {
         alert('mainPageFunction called');
      }
   }
}

Now you need to add an event listner to your JavaScript bottom like below and set the middle parameter as your method name:
window.addEventListener("message", mainPageFunction, false);

And you have to call this "mainPageFunction()" method from iframe page like below:
parent.postMessage({'message':'message', 'action': 'callparent'},'*');


My VisualForce Page:
<apex:page showheader="false" sidebar="false">
  
  <style>
      body{
          background-color: yellow;
      }
  </style>
  
  <script>
      
      function mainPageFunction(event){
          
          if (event.data && event.data.action) {
            
            if (event.data.action == 'callparent') {
              alert('mainPageFunction called');
            }
          }
       }   
      
      window.addEventListener("message", mainPageFunction, false);
      
  </script>
<div style="margin-left: 20px;">
<h1 style="font-size: 40px;">
This is my main page</h1>
<apex:iframe height="200px;" html-style="border: 1px solid; background-color: white; margin-top: 30px;" src="https://sfdciframeexample.herokuapp.com/" width="800px;">
</apex:iframe></div>
</apex:page>

My HerokuApp Page:

<html>
<head>
  <script type="text/javascript">
    
    function callParentFunction(){

        parent.postMessage({'message':'message', 'action': 'callparent'},'*');
    }

  </script>
</head>


<div class="jumbotron text-center">
  <div class="container">
    
    <h1>
This is a sample app delpoyed on heroku</h1>
</div>
</div>
<div class="container">
    <button onclick="callParentFunction();">Call Parent function</button>
  
  
</div>
</html>
Now if click the button "Call Parent function" from iframe to call this parent JavaScript method, it will be called successfully.



Newest Older

Related Posts

Post a Comment

Subscribe Our Newsletter