Wednesday, July 3, 2013

Workaround for issues with XPage in iframe on external website

Update, 03.03.14: We had some further issues with Chrome and form submission. Code snippet updated with workaround.

A colleague of mine had some issues with an XPage running in an iframe on a customer's website. The customer notified us that some users with Chrome/Safari had issues with the page going blank.

When doing partial refresh, the page went into a reload loop. I did a quick check, and couldn't find anything wrong with the code. I believe it has something to do with cross domain cookies and Webkit.

My workaround was to have a script block that adds the SessionID parameter that was previously added in certain circumstances on earlier versions of XPages. The script block is only loaded for Chrome/Safari, and the code only runs when the XPage is in a frameset/iframe.

<xp:scriptBlock>
 <xp:this.loaded><![CDATA[${javascript:return ( context.getUserAgent().isChrome() || context.getUserAgent().isSafari() );}]]></xp:this.loaded>
 <xp:this.value><![CDATA[(function(){
// Fix for safari/chrome when page is in iframe. Cookie with SessionID seems to be discarded between requests
// Workaround: Set parameter for SessionID
var queryString = document.location.search;
var sessionIdParameter = 'SessionID=' + '#{javascript:return facesContext.getExternalContext().getRequest().getSession().getId();}';
if( self !== parent && queryString.indexOf( 'SessionID' ) === -1 ){
 if( queryString === '' ){
  document.location.search = sessionIdParameter;  
 } else {
  document.location.search = queryString + '&' + sessionIdParameter;
 } 
}

// Add SessionID parameter to form action if set in URL to preserve session
if( queryString.indexOf( 'SessionID' ) !== -1 ){ 
 var form = document.forms[0];
 if( !form ){
  return;
 }
 
 var formAction = form.action;
 var parameterDelimiter = '&';
 if( formAction.indexOf( '?' ) === -1 ){
  parameterDelimiter = '?';
 }
 form.action = form.action + parameterDelimiter + sessionIdParameter;  
}
})();]]></xp:this.value>
</xp:scriptBlock>