How to bypass cross domain issues to display SharePoint Online pages within Iframe from an external Domain

Sriram Varadarajan
 
Solution Architect
October 25, 2016
 
Rate this article
 
Views
28294

By default, SharePoint Online doesn’t allow to access it’s pages via iframe from an external application, in this article, we can see how to override that restriction and access SharePoint Online Pages from a external domain.

The following concepts were used as an approach to resolve the above said use case.

  • Oauth Authentication
  • Sharepoint pages
  • Allow Framing for webpart pages
  • Jquery
  • Virtual directory enabled for HTTPS protocol

Stepwise Implementation

Creation of SharePoint Page

  • Open your SPO site and create a sharepoint site page that needs to be displayed inside the Iframe element name it as iframe.aspx.
  • Now open the SharePoint designer and navigate to the above created page(iframe.aspx).
  • Edit the page in advanced mode and append the below content inside the PlaceHolderPageTitle content element

<WebPartPages:AllowFraming runat="server"/>

clip_image002

· Now save the page and note down the url of the page like this

clip_image004

Note: if you want your entire site to be available in your IFRAME of external application then you need to enable ALLOW Framing in your master page. For details please refer

Creation of external web application

Create a external web application and have 2 html pages(TestIframe, TestIframe2) created.

The web application should be HTTPS enabled.

Now edit the TestIframe2.html page and have the following code

 <html>
 <head>
 	<title>Cross-domain sample</title>
 </head>
 <body>
 	<div>
 		<iframe style="width:100%; height:500px;" src="https://XXXXXXXXX.sharepoint.com/sites/AB345/SitePages/iframe.aspx"></iframe>
 	</div>
 </body>
 </html>

In the above code src should be the url to the iframe.aspx page that we created in the above step.

Next open TestIframe.html and paste the following code

 <html xmlns="http://www.w3.org/1999/xhtml">
 <head runat="server">
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
 <title>Login Page</title>
 <script type="text/javascript" language="javascript">
     $(document).ready(function(){
         window.location.href = "https://XXXXXXXXXXXX.sharepoint.com/_layouts/15/OAuthAuthorize.aspx?state=hostname=localhost&redirect_uri=https://localhost/IFrametest/testiframe2.html&resource=https://graph.windows.net&response_type=code&client_id=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
     });	
 </script>
 </head>
 <body>
 	<div>
 		Login Page .......................
 	</div>
 </body>
 </html>

In the above code sample three query string parameters needs to be updated with your application values

Hostname – should be the hostname of your external web application

redirect_uri – should be the url to the TestIframe2.html page in the external web application that contains the Iframe element.

client_id – using the above 2 query string parameters, register your app in the SPO site and generate new client ID. Use this client id here as the query string value.

 

 

Note – while registering the app, in the appinv.aspx page in SPO, assign the following permssion request XML

<AppPermissionRequests AllowAppOnlyPolicy="true" ><AppPermissionRequest Scope="http://sharepoint/content/sitecollection/web" Right="FullControl" /></AppPermissionRequests>

For more info on how to register new Apps with SPO, refer this link.

Screen Images

 

· Now open the TestIframe.html from the Chrome Browser (Suggest to use Chrome). It will prompt for SPO login page and on successful login, will get redirected to SPO oauth page to Trust our page as shown in the below pic.

clip_image006

· Click on the “Trust It” button and the page will get automatically redirected to our TestIframe2.html page that contains the Iframe element.

clip_image007clip_image008Flow Diagram

clip_image009
clip_image010
clip_image011
clip_image012
Category : CORS, Office 365, SharePoint

Author Info

Sriram Varadarajan
 
Solution Architect
 
Rate this article
 
Sriram is a Technology Evangelist with 15+ years experience in Microsoft Technologies. He is an enterprise architect working for large pharmaceutical organization which has presence globally with largest Microsoft implementation ...read more
 

Scroll to the Mandatory Field validation – Issue with Iframe – ScrollinToView- JavaScript

Sathish Nadarajan
 
Solution Architect
April 20, 2016
 
Rate this article
 
Views
7203

Recently met with a strange small issue like setting up the focus. In one of the project, I have the AppPart and an lengthy App hosted inside that. Hence, both the SharePoint Site as well as the AppPart is having the Scroll Bars as shown in the figure.

clip_image002

Now, the issue was like at the bottom of the app, I have a submit button and on click of the submit button, the scroll should move up and focus should be set on the mandatory fields, which were not given the inputs. I tried with the asusual focus methods and the setfocus etc.,

But everything was working with the normal pages. But when I deploy inside this iFrame, nothing works. And the most important thing is, the SharePoint and the AppWeb are hosted on different domains. Since the document.domain differs, we cannot call the DOM Object.

While doing some googling, found a solution for this issue. The native JavaScript code will be very much helpful for this scenario.

Just a small div surrounding the control. Then we need to use the method scrollIntoView().

 if (($("#ddlDate").val() === "") || ($("#ddlDate").val() === "null")) {
                  document.getElementById("divDueDateCtrl").scrollIntoView();
                  
              }
 

Though it seems very small, it ate some hrs of my time to fix.

Happy Coding,

Sathish Nadarajan.

Category : JavaScript, SharePoint

Author Info

Sathish Nadarajan
 
Solution Architect
 
Rate this article
 
Sathish is a Microsoft MVP for SharePoint (Office Servers and Services) having 15+ years of experience in Microsoft Technologies. He holds a Masters Degree in Computer Aided Design and Business ...read more
 

“The Content cannot be displayed in a frame” – Display another SharePoint WebApplication inside an iFrame of our SharePoint Site

Sathish Nadarajan
 
Solution Architect
October 27, 2014
 
Rate this article
 
Views
68217

We faced an issue with the Authentication while working with the Cross Site Publishing. The problem statement is something like the below.

1. 2 Web Applications. Authoring and Publishing.

2. On the Publishing Site, render some of the Contents from the Authoring

3. The Publishing Site is authenticated while the user logged in.

4. But the Authoring Site was not authenticated at that time.

5. Hence, the contents will not be rendered properly on the Publishing Site.

Resolution:

To overcome this, we thought of having a hidden iFrame in the master page of our Publishing portal, and inside the iFrame, let us load the Authoring Web Application silently. We were on the process of this. But in that also, I faced some problem.

Let me explain that with the help of a sample page itself.

Let us have a Page and add a Content Editor WebPart on it. On the Content Area, I am rendering the iFrame as below.

 <iframe id="test" src="http://c4968397007:1001/sites/assets/Pages/default.aspx" style="width: 1260px; height: 150px;"></iframe>

Then the screen renders like below.

clip_image002

The error message, we will be getting is like

“The Content cannot be displayed in a frame”

As part of fixing this, issue, I was tracing this response on the Fiddler and on the fiddler report, there is an attribute called X-FRAME-OPTIONS and by default it was like SAME ORIGIN.

clip_image004

Then, we identified that, because of this only, the page is not rendering inside an IFrame.

Now, there nothing to do with the Publishing portal. We need to make the Content Site to render inside an IFrame. Hence, the following change needs to be done on the Master page of the Content Site Portal.

 <WebPartPages:AllowFraming runat="server"  />

Just Add the above mentioned tag above the head Tag of the Master Page. The best way is, download the Seatle.Master page file. Rename it as Seatle_Custom.Master. Add this line. Upload back to the Master page gallery. Map this new Seatle_Custom.Master file to the Content Authoring Site Collection.

Now, coming back to our publishing site and do a refresh. Now, the site loads inside the iFrame.

clip_image006

Though it is very simple, it took some long hours to identify and fix this.

Hope this will be helpful.

Find the modified Master Page Here.

Happy Coding.

Sathish Nadarajan.

Author Info

Sathish Nadarajan
 
Solution Architect
 
Rate this article
 
Sathish is a Microsoft MVP for SharePoint (Office Servers and Services) having 15+ years of experience in Microsoft Technologies. He holds a Masters Degree in Computer Aided Design and Business ...read more
 

Return Value from ClientContext.ExecuteQueryAsync in Javascript CSOM on SharePoint 2013

Sathish Nadarajan
 
Solution Architect
November 16, 2013
 
Rate this article
 
Views
42513

Most of the time, we would have been came across to fetch the list items using Javascript CSOM object model using SP.JS. Whenever we want to do some action, we can very well do that on the Success method. But I faced a different scenario, where I need to return the fetched list item to the parent method which is calling from an iFrame. Hence, the remaining process needs to be done from the iFrame. Not from our javascript method. Let the picture speaks more about this.

image

With the above scenario, the code would be something like,

 function GetRating(sender, args) {
 
                
         var ctx = new SP.ClientContext(“http://sathishserver:20000/sites/VHS/”);
         var web = ctx.get_web();
         this.list = web.get_lists().getByTitle(ListName);
         this.listItems = list.getItemsByID(ItemID);
 
         ctx.load(listItems, 'Include(ID, AverageRating)');
         ctx.executeQueryAsync(Function.createDelegate(this, GetRatingSuccess), Function.createDelegate(this, GetRatingFailure));
 
     }
 
 function GetRatingSuccess (sender, args) {
 
         RatingValue = listItems.itemAt(0).get_item("AverageRating");
         
 
     }
 
     function GetRatingFailure (sender, args) {
 
         alert(‘GetRating():' + args.get_message());
 
     }
 

Here, the GetRatingSuccess method is having the RatingValue. This value needs to be returned to the method within iFrame. I was trying with different options like Windows.Addlistener, attachevent, callback functions etc., but nothing had worked out. Since this is working with async thread, even the thread.sleep , settimeout, setinterval, nothing had worked out. At last, found an workaround. Instead of trying to return a value from this async function, call another method on the iFrame by passing this RatingValue as argument. This solves my requirement. J . The sample would be somewhat like

 function GetRatingSuccess (sender, args) {
 
         RatingValue = listItems.itemAt(0).get_item("AverageRating");
         
 document.getElementById("iFrameID").contentWindow.Success(RatingValue);
 
     }
 

The “Success” is the method which will be available on the iFrame.

This is very simple right. But to arrive this, spent a lot of time digging into the Callback and eventlisteners for async method. But I could say that, it is a quality time. J .

Hope this helps. Thanks.

Happy coding.

Sathish Nadarajan.

Author Info

Sathish Nadarajan
 
Solution Architect
 
Rate this article
 
Sathish is a Microsoft MVP for SharePoint (Office Servers and Services) having 15+ years of experience in Microsoft Technologies. He holds a Masters Degree in Computer Aided Design and Business ...read more
 

Leave a comment