在iFrame中嵌入Google Apps脚本的问题 [英] issue with Embedding Google Apps Script in an iFrame

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

问题描述

我有一个多页Web应用程序.我想要登录后,用户看到他的队友列表并标记他们的出勤状态.我的问题是,我无法在iFrame中而不是在Google脚本原始版本中显示它!例如,我想通过iFram将其存储到我自己的网页中.这是两天的时间,我无法克服这个问题,在这方面我读了很多文章,并且从头开始尝试了另一个应用程序,但是还没有运气.你们能帮我这个忙吗?

i have a multi page Web App. I want after log in, user sees the list of his team mate and mark 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 iFram 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. Can you guys please help me on this?

为澄清起见,我正在使用渲染功能将用户重定向到框架内.因此,正如@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);
} 

我可以从主页转到登录页面,但是在那之后,即使它也不允许我访问Google!
在某些情况下,还会在框架内返回空白页!

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

这是我的客户端Java脚本示例代码.

Here is my sample code for the client side java script.

      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页面上的基本目标切换为"_top"或"_self".

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

请告知, M

推荐答案

问题:

您可以尝试

Issue:

You can try

window.top.location = link;

它将链接加载到顶部框架中.如果您要在网站中构建Web应用程序本身,则应使用

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 ...的框架开始针对具有URL ...的框架进行导航.试图进行导航的框架已被沙箱化,因此不允许其祖先导航.

Unsafe JavaScript attempt to initiate navigation for frame with URL ... from frame with URL .... The frame attempting navigation is sandboxed, and is therefore disallowed from navigating its ancestors.

解决方案:

  • 使用window.postMessage()
  • Solution:

    • Use window.postMessage()
    • 
      ==================
      |Your site       |<-mysite.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>
      

      参考文献:

      • postMessage
      • iFrame
      • References:

        • postMessage
        • iFrame
        • 这篇关于在iFrame中嵌入Google Apps脚本的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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