Alumni Association
Alumni Association

Reputation: 21

How to set iframe attributes in Google appScripts' HtmlService.SandboxMode.IFRAME

I created a Google Sites page that will display a quick "Our Association Welcomes" and then an appScript under it that will display whatever names are listed in a Google Spreadsheet. When you visit the site everything works great, but the intended use of this project is for a digital signage board in our lobby using RiseVision. RiseVision uses a Web Page Widget that just shows a page and updates it however often specified. Now on the RiseVision display the page will show the "Our Association Welcomes" message, but the names will not display. In the console I can see an error

"Refused to display 'https://...' in a frame because it set 'X-Frame-Options' to 'SAMEORIGIN'.

Now I know there is a whitelist iframe attribute called allow-same-origin but I can't figure out where to apply it as I believe the frame is created through the HtmlService.

Here is the Google Sites page I made.

Here is the preview of a presentation with just the Web Page Widget loaded.

And here is the appScript, js followed by the HTML it returns:

var DOC_ID = "1E969qh8NenAXICpnuuYSIICM9CzUh888FnFULR-gfls";
function doGet(){return HtmlService.createHtmlOutputFromFile('nameBox.html')
   .setSandboxMode(HtmlService.SandboxMode.IFRAME);}  

function createNameArray(){
  var sheet = SpreadsheetApp.openById(DOC_ID).getSheetByName("WelcomeNames");
  var names = sheet.getDataRange().getValues();
  var nameArray = new Array;
  var permaName = names[1][2];
  for(var i=0;i<names.length;i++){
    nameArray[i] = names[i][0];
  }
  return nameArray;
}

and the HTML

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <script>
       function onSuccess(nameArray) {
          var i = 0;
    //display style: 0=cycle; 1=all names; 2=one name only
          var displayStyle = 2;
    // cycle through list of names one at a time
          if (displayStyle == 0){
            var timer = setInterval(cycleNames, 120000);
            function cycleNames(){
              if (i <= nameArray.length){
                var div = document.getElementById("textDiv");
                div.textContent = nameArray[i];
                var text = div.textContent;
                i++;
              }
              if (i > nameArray.length){i = 0;}
            }
          }
    // Display all names at once in columns 
          else if (displayStyle == 1){
            function tableCreate() {
              var body = document.body,
                  tbl  = document.createElement('table');
              tbl.style.width = '100%';
              var numNames = nameArray.length;
              var col, row, count;
              if (numNames <= 5){col = 1;}
              else if ((numNames > 5) && (numNames < 11)){col = 2;} 
              else if (numNames > 11){col = 3;}
              row = Math.ceil(numNames/col);
              count = 0;
              for(var x=0;x<row;x++){
                  var tr = tbl.insertRow();
                  for(var y=0;y<col;y++){
                      if ((count <= numNames) && (nameArray[count]!=null)){
                        var td = tr.insertCell();
                        td.appendChild(document.createTextNode(nameArray[count]));
                        count++;
                      } else {td.appendChild(document.createTextNode(" "));}
                  }
              }
              body.appendChild(tbl);
            }  
            tableCreate();
          }              
    // Display one name perminantly
          else if (displayStyle == 2){
            var div = document.getElementById("textDiv");
            div.textContent = "Jordan";
            var text = div.textContent;
          }
       }
       google.script.run.withSuccessHandler(onSuccess).createNameArray(); 
    </script>
    <style>
    #textDiv {
       text-align: center;
       color: red;
       font-family: verdana, arial;
       font-size: 48px;
       font-weight: bold;
    }
    table, td, tr {
       padding: 20px;
       color: red;
       text-align: center;
       font-family: verdana, arial;
       font-size: 30px;
       font-weight: bold;
    }
  </style>
  </head>
  <body>
    <div id="textDiv"></div>
  </body>
</html>

I really think my issue is going to be in the doGet() function. Here it is broken up a little more for clarity.

function doGet(){
  var app = HtmlService.createHtmlOutputFromFile('nameBox.html');
  app.setSandboxMode(HtmlService.SandboxMode.IFRAME);
  return app;
}

If it returns an HtmlOutput object that creates an iframe(?), where can I add in an attribute to let it allow same origin? Or is that even possible? Any help on this would be greatly appreciated. My web dev skills have rusted over and as such I've been racking my brain on this for a couple weeks now.

Upvotes: 2

Views: 1648

Answers (1)

Sam
Sam

Reputation: 105

Kind of late but just putting it out there so others can use this info.

To allow google script returning a html output to be used in an iframe in other website your settings should be like--

    return HtmlService
   .createTemplateFromFile('form')// form or whatever your html file is called
   .evaluate()
   .setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);

This example doesn't assign any variable, directly returns the HtmlService.

You should use 'createTemplateFromFile' followed by 'evaluate()' and set 'XFrameOptionsMode' to ALLOWALL, not 'createHtmlOutputFromFile'.

Hope this helps

Upvotes: 1

Related Questions