Scenario
the following is the scenario:
- You have a page with a JavaScript method.
- The page has an App Part too that displays from a PHA application.
- The App Part needs to invoke the JavaScript method on the page.
- Due to cross-domain issues, the App Part cannot invoke the parent page's method.
App Parts are rendered in IFrames. The scenario is depicted below:
By default SharePoint prevents cross-domain script calls to avoid the following security vulnerabilities:
- An IFRAME code can manipulate the parent page's HTML DOM objects.
- An IFRAME code can unwantedly invoke the parent page's script methods.
Note
Please note that the cross-domain issue won't occur if the page and IFRAME page happens to be in the same SharePoint library. In our case the IFRAME content is an App Part that is coming from an externally hosted PHA application.
Solutions
The following are the solutions possible here:
- Use Allow Framing control on the page.
- Use SP.RequestExecutor wiring.
- Use JavaScript Post Message functionality.
Here I would like to show the JavaScript Post Message functionality.
JavaScript Post Message
The window.PostMessage() method allows safe communication across cross-boundary pages. Here the invoker is passing a message string to the target. The target may choose to process or ignore the message.
Implementation
For simplicity, I am avoiding creating the PHA application. I would like to show the core functionality. Create a new page in SharePoint.
Add a content web part and insert the following code into it. (See parent.html)
- <script>
- function parentmethod()
- {
- alert("Parent Method Invoked!");
- }
- window.onmessage = function(e)
- {
- if (e.data == 'ok')
- {
- parentmethod();
- }
- };
- </script>
- <iframe src="/SiteAssets/frame.html"></iframe>
The code above does the following:
- Create a method named parentmethod() that displays an alert message.
- Create a message listener method for any incoming messages.
- Create an IFRAME displaying the child page.
Now you need to upload the following content to the Site Assets library. Name it frame.html. (See frame.html)
- <input type="button" value="Click Me to invoke Parent Method" onclick="parent.postMessage('ok', '*');"> </input>
Save the changes and your page looks as in the following now.
Click on the button and you should be able to see the message box shown below.
The following is the functionality summary depiction.
This resolves the cross-domain script call issue.
Summary
In this article, we explored cross-domain issues of the App Part and a solution for it. The scripts are added to the article.