0

I'm working on a standalone script that will eventually be published as an add-on. It will have a sidebar users interact with and from there they can launch the Google File Picker to upload a report for processing. I previously was looking for a way for the sidebar to know that the file picker was done. I replicated this answer successfully and got the File picker dialog to send a message back to the sidebar indicating it was finished. However, the console is full of some errors and warnings that I'm wondering if I should be concerned about. The errors are:

Unsafe attempt to initiate navigation for frame with origin 'https://docs.google.com' from frame with URL 'https://***.googleusercontent.com/userCodeAppPanel'. The frame attempting navigation of the top-level window is sandboxed, but the flag of 'allow-top-navigation' or 'allow-top-navigation-by-user-activation' is not set.

DOMException: Blocked a frame with origin "https://###.googleusercontent.com" from accessing a cross-origin frame. at findSideBar (https://###.googleusercontent.com/userCodeAppPanel:80:18) at w0.pickerCallback [as Fb] (https://###.googleusercontent.com/userCodeAppPanel:98:11) at w0._.h.iV (https://apis.google.com/_/scs/apps-static/_/js/k=oz.gapi.en.uAzDleg2hnU.O/m=picker/rt=j/sv=1/d=1/ed=1/am=AQ/rs=AGLTcCMT6b3QcRI88QolvkcdUjC8YnoTvA/cb=gapi.loaded_0:740:393) at d (https://apis.google.com/_/scs/apps-static/_/js/k=oz.gapi.en.uAzDleg2hnU.O/m=picker/rt=j/sv=1/d=1/ed=1/am=AQ/rs=AGLTcCMT6b3QcRI88QolvkcdUjC8YnoTvA/cb=gapi.loaded_0:215:143) at b (https://apis.google.com/_/scs/apps-static/_/js/k=oz.gapi.en.uAzDleg2hnU.O/m=picker/rt=j/sv=1/d=1/ed=1/am=AQ/rs=AGLTcCMT6b3QcRI88QolvkcdUjC8YnoTvA/cb=gapi.loaded_0:210:1)

Refused to get unsafe header "X-HTTP-Status-Code-Override"

The first error I have seen before, however, the second is new and relevant to sending the message from the file picker dialog back to the sidebar.

It's worth mentioning that everything still works. My question is primarily are these errors I should be worried about, will they cause problems when the add-on is being reviewed before being published, and how can I correct them?

I've included below my code for the sidebar creation, picker creation, and the relevant code for sending the message from the picker to the sidebar.

Sidebar Creation:

function buildSidebar(type) {
  hideColumns();
  hideRows();
  hideSheets();
  if(type == 'setup' || checkSetup()) {
    var html = HtmlService.createTemplateFromFile('SidebarSetupHTML')  
    .evaluate()
    .setTitle('Test');
  } else {
    var html = HtmlService.createTemplateFromFile('SidebarMainHTML')  
    .evaluate()
    .setTitle('Test');    
  }
  SpreadsheetApp.getUi().showSidebar(html);
}

Picker Creation:

function showPicker() {
  var html = HtmlService.createHtmlOutputFromFile('PickerHTML.html')
      .setWidth(600)
      .setHeight(425)
      .setSandboxMode(HtmlService.SandboxMode.IFRAME);
  SpreadsheetApp.getUi().showModalDialog(html, 'Select Report(s)');
}

Picker Message Code:

function pickerCallback(data) {
  var action = data[google.picker.Response.ACTION];
  if (action == google.picker.Action.PICKED) {
    (function findSideBar(limit) {
      let f = window.top.frames;
      for (let i = 0; i < limit; ++i) {
        try {
          if (
            f[i] /*/iframedAppPanel*/ &&
            f[i].length &&
            f[i][0] && //#sandboxFrame
            f[i][0][0] && //#userHtmlFrame
            window !== f[i][0][0] //!== self
          ) {
            console.info('Sidebar found');
            var sidebar = f[i][0][0];
            sidebar.modalDone('PICKED'); //Modal has finished
            console.log('Message sent');
            google.script.host.close();
          }
        } catch (e) {
          console.error(e);
          continue;
        }
      }
    })(10);
  }
}

Sidebar launch picker and receive message:

  function testPicker() {
    google.script.run.withSuccessHandler(pickerResponse).showPicker();
  }

  function pickerResponse(e) {
    (async () => {      
      let receiver = new Promise((res, rej) => {
        window.modalDone = res;
      });
      var message = await receiver;
      console.log('message received');
      if(message == 'PICKED' || message == "NOT_PICKED") {
        console.log(message);
      }
      //Do what you want here
    })();
  }
  • Although I'm not sure whether this is the direct solution of your issue, I proposed an answer. Could you please confirm it? If I misunderstood your question and that was not useful, I apologize. – Tanaike Oct 16 '21 at 05:37
  • Amazingly, this fixed nearly all of the errors. However, I am still getting the 'Refused to get unsafe header "X-HTTP-Status-Code-Override"' error/warning for some reason. Is this something that I should be worried about? – Josh Bunzel Oct 16 '21 at 05:48

1 Answers1

1

When I saw your script, I thought that the reason for your issue might be the loop after the if statement was true. So for example, when the if statement is true, how about putting break in the last line? So, how about the following modification?

From:

if (
  f[i] /*/iframedAppPanel*/ &&
  f[i].length &&
  f[i][0] && //#sandboxFrame
  f[i][0][0] && //#userHtmlFrame
  window !== f[i][0][0] //!== self
) {
  console.info('Sidebar found');
  var sidebar = f[i][0][0];
  sidebar.modalDone('PICKED'); //Modal has finished
  console.log('Message sent');
  google.script.host.close();
}

To:

if (
  f[i] /*/iframedAppPanel*/ &&
  f[i].length &&
  f[i][0] && //#sandboxFrame
  f[i][0][0] && //#userHtmlFrame
  window !== f[i][0][0] //!== self
) {
  console.info('Sidebar found');
  var sidebar = f[i][0][0];
  sidebar.modalDone('PICKED'); //Modal has finished
  console.log('Message sent');
  google.script.host.close();
  break; // <--- Added
}

Note:

When I tested a following sample script for a custom dialog on Google Docs (For example, it's Google Spreadsheet),

<script>
  google.script.host.close();
  alert("ok");
</script>

I confirmed that the alert window is opened and also, the dialog is closed. So I thought that google.script.host.close() might work with the asynchronous process.

For example, when google.script.run with the high process cost is used as follows,

<script>
  google.script.host.close();
  google.script.run.withSuccessHandler(_ => alert("ok2")).myFunction();
  alert("ok1");
</script>

it seems that myFunction() and alert("ok2") are not run because the dialog is closed before run myFunction(), while alert("ok1") is run. On the other hand, when the process cost is low, it seems that the script after google.script.host.close() is run.

From these situation, as an attempt, I have proposed to add break after google.script.host.close() for OP's issue.

Reference:

Tanaike
  • 181,128
  • 11
  • 97
  • 165
  • @Josh Bunzel Thank you for replying. About `X-HTTP-Status-Code-Override`, unfortunately, in my environment, I couldn't confirm this. This is due to my poor skill. I deeply apologize for this. By the way, I tested it using Chrome 94.0.4606.81. How about this? – Tanaike Oct 16 '21 at 05:56
  • Hmmm.. I thought `google.script.host.close()` immediately stopped all loops - as the sidebar is closed. – TheMaster Oct 16 '21 at 07:28
  • 1
    @TheMaster I thought that `google.script.host.close()` might work with the asynchronous process. For example, when a sample script of `google.script.host.close(); alert("ok");` is used for a custom dialog on Google Docs, the alert window is opened and also, the dialog is closed. So as an attempt, I have proposed to add `break` after it. – Tanaike Oct 16 '21 at 07:34
  • 1
    @TheMaster For example, when `google.script.run` with the high process cost is used like `google.script.host.close(); google.script.run.myFunction();`, it seems that `google.script.run.myFunction()` is not run because the dialog is closed before run `google.script.run.myFunction()`. But, when the process cost is low, it seems that the script after `google.script.host.close()` is run. – Tanaike Oct 16 '21 at 07:37
  • 1
    Interesting. Thanks for showing your results. Maybe you should add it to the answer. – TheMaster Oct 16 '21 at 07:41
  • 1
    @TheMaster Thank you for replying. I added a Note section including the above explanation. – Tanaike Oct 16 '21 at 07:52