google-apps-scriptweb-applications

Properly setting the XFrameOptionsMode for Google Apps Script Iframes


I'm reading through the Google Apps Script docs in order to get a grip. Below is my attempt in my .gs file to allow for my web app to be embedded as an Iframe...

function doGet(e) {

  //URI PARAMETER VALUE(S)
  let mpage = 'mapp';
  if ('page' in e.parameters) {
    mpage = e.parameters['page'][0]
  }

  try {

    //TRY TO ENABLE THE WEB APP WITH CUSTOM DATA USAGE
    let html = HtmlService.createTemplateFromFile(mpage);
    html.data = { title: mpage, e: e }
    
    //THE ONLY WAY I KNOW OF ADDING META TAGS TO THE APP
    let htmlOutput = HtmlService.createHtmlOutput(html.evaluate().setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL));
    htmlOutput.addMetaTag('viewport', 'width=device-width, initial-scale=1, shrink-to-fit=no');
    return htmlOutput;
  }
  catch (err) {
    //IF THERE IS AN ERROR, DISPLAY THE ISSUE
    const html = HtmlService.createHtmlOutput('Page Not Found : ' + JSON.stringify(err));
    return html;
  }
}

Here is my html example of the actual embed....

 <iframe src="https://script.google.com/a/macros/.../exec?page=mapp-gallery" frameborder="0" width="100%" height="100%" scrolling="no">
 </iframe>

But when I attempt to embed this on any page, I get the following image...

enter image description here

My Apps Script is set to anyone can view. So I am assuming that within my .gs code, the HtmlService.XFrameOptionsMode.ALLOWALL is not set properly.

I can see my web app in Incognito mode if I go there directly through the browser. But how can I fix this situation so that my iframe properly reflects my web app?


Solution

  • let htmlOutput = HtmlService.createHtmlOutput(html.evaluate().setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL));
    

    HtmlTemplate.evaluate() already returns HtmlOutput. And you set ALLOWALL option on it. But, by feeding the HtmlOutput back to HtmlService.createHtmlOutput, you're creating a new HtmlOutput without a xframe option set on the new object. Fix it by removing redundant and buggy calls:

    let htmlOutput = html.evaluate().setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
    

    Make sure to redeploy or create a new version on the existing deployment. You might also want to set the same on the catch block's HtmlOutput.