从父级导航嵌入式 Google Apps Script iFrame [英] Navigating embedded Google Apps Script iFrame from the parent

查看:23
本文介绍了从父级导航嵌入式 Google Apps Script iFrame的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个多页 Web 应用程序.我想登录后,用户看到他的队友列表并标记他们的出勤状态.我的问题是我无法在 iFrame 而不是谷歌脚本中显示它.

I have a multi-page Web App. I want after login, a user sees the list of his teammate and marks their attendance status. My issue is I can't show that in an iFrame rather than google script original one.

例如,我想将它嵌入到我自己的网页中.这两天我无法解决这个问题,我阅读了很多这方面的帖子,还从头开始尝试了另一个应用程序,但还没有成功.

For instance, I wanted to iFrame it to my own web page. it is two days I can't overcome this issue, I read lots of posts in this regard and also tried another app from scratch, but no luck yet.

为了澄清起见,我正在使用渲染功能将用户重定向到框架内.所以正如@theMaster 提到的,它不是一个多页面的 Web 应用程序.

For clarification, I am redirecting the user inside the frame using render function. So as @theMaster mentioned it is not a multi-page Web App.

这是我的 doGet 和 Render 函数:

here is my doGet and Render functions:

function doGet(e){
    // Logger.log(e);
    Route.path("login",loadLogin);  
    Route.path("admin",loadAdmin);  
    Route.path("view",loadView);
    Route.path("form",loadForm);
if (e.parameters.id){
  LastID=e.parameters.id[0]; 
}
if (e.parameters.t){
  curT=e.parameters.t[0]; 
}  
if (Route[e.parameters.v]) {
  return Route[e.parameters.v]();
} else {
  return render('W-home');
  }    
}

function render(file, argObject){
    var page = HtmlService.createTemplateFromFile(file);
    if (argObject){
        var keys = Object.keys(argObject);
        keys.forEach(function (k){
        page[k]=argObject[k];
        });
    }
    var evalPage =page.evaluate();
    // if (!xFrame){return evalPage;};
    return evalPage.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
} 

我可以从主页转到登录页,但在那之后,即使它也不让我去谷歌.在某些情况下,也只是在框架内返回一个空白页面.

I can go from home page to login page, but after that, even it doesn't let me go to google. In some cases also just returns a blank page inside the frame.

这是我的客户端 JavaScript 示例代码.

Here is my sample code for the client-side JavaScript.

function goToForm(EmpNo) {
  var link = "<?!=ScriptApp.getService().getUrl()?>" + "?v=form&id=" + EmpNo[1] + "&t=" + EmpNo[2];
  location.href = link;
  // I tried different way to see if i can conqure this! 
  // if (clickBTN= 'a') {
  //   window.open(link, "_self");
  // } if (clickBTN= 'b') {
  //   location.href=link;
  // } if (clickBTN= 'c') {
  //   openNewURLInTheSameWindow(link);
  // }          
}

我还有两个全局变量 xFrame 用于将 XframeOptionsMode 设置为 allowAll 或不和 base 将 HTM 页面上的基本目标切换为 "_顶"或_self".

I also have two global variables xFrame to set XframeOptionsMode to allowAll or not and base to switch base target on the HTM pages to "_top" or "_self".

推荐答案

问题:

你可以试试

window.top.location = link;

它将在顶部框架中加载链接.如果您在网站中构建网络应用程序本身,那么您应该使用

It'll load the link in the top frame. If you are framing the web-app itself in your website, then you should use

window.parent.parent.location = link;

但这行不通,因为沙箱会阻止导航文档中的其他框架.sandbox="allow-top-navigation" 只允许顶部框架导航,不允许中间框架.由于顶部框架是您的网站而不是 script.google.com,因此无法导航并且您会收到错误

But this won't work because the sandbox prevents navigating other frames in the document. sandbox="allow-top-navigation" only allows top frame navigation and not the intermediate frames. Since the top frame is your site and not script.google.com, it can't be navigated and you'll get the error

不安全的 JavaScript 尝试为 URL https://myexamplesite.com... 的框架启动导航...来自 URL https://*.googleusercontent.com/的框架...导航是沙盒的,因此不允许导航其祖先.

Unsafe JavaScript attempt to initiate navigation for frame with URL https://myexamplesite.com... from frame with URL https://*.googleusercontent.com/... The frame attempting navigation is sandboxed, and is therefore disallowed from navigating its ancestors.

解决方案:

  • 使用window.postMessage()
  •   
    ==================
    |Your site       |<-myexamplesite.com [TOP#0]
    |                |
    | =============  |
    | |GASWebApp  |<-|--script.google.com[Frame#1]
    | |           |  |
    | |=========  |  |
    | ||SandBox|  |  |
    | ||User   |<-|--|-- Where your html code is
    | ||Frame  |  |  |  (*.googleusercontent.com) 
    | |=========  |  |   [Frame#2 and #3(Double nested iframe)]
    | |           |  |
    | =============  |
    |                |
    |                |
    |                |
    ==================
    

    片段:

    沙盒 Html:

    <script>
    if(window.parent.parent !== window.top){ //if #1 !== top
      //Framed in a another web-app
      //TODO Use proper target origin instead of *
       window.parent.parent.parent.postMessage("[FRAME#1_LINK_TO_CHANGE]","*");//Post to #0
    }
    </script>
    

    顶部框架(#0):

    <!-- Frame the Apps script Web-App Frame#1-->
    <iframe
      src="https://script.google.com/macros/s/[SCRIPT_DEPLOYMENT_ID]/exec"
      >Loading...</iframe
    >
    <script type="text/javascript">
      const handleMessage = function(event) {
        if (
          event.origin !==
          'https://[SCRIPT_ORIGIN]script.googleusercontent.com'
        ) {
          alert('Origin Disallowed');
          return;
        }
          //TODO Check syntax of event.data before changing iframe src
          document.querySelector('iframe').src = event.data; //Change #1 Link
      };
      window.addEventListener('message', handleMessage);
    </script>
    

    参考:

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆