【问题标题】:How to change height of GAS iframe (in WordPress) using iframe-resizer如何使用 iframe-resizer 更改 GAS iframe 的高度(在 WordPress 中)
【发布时间】:2021-04-15 23:03:01
【问题描述】:

我想将我的 Google Application Script Web 的 iframe 添加到 WordPress 网站。我想摆脱滚动条。看图。

不确定 iframe-resizer 是否因为此错误消息而无法工作

Failed to execute 'postMessage' on 'DOMWindow': The target origin provided
('https://script.google.com') does not match the recipient window's origin ('http://rsness.8u.cz').

从 iframe-resizer troubleshooting 页面看起来这个错误不一定是问题

This error occurs when the parent window tries to send a message to the iframe before it has loaded. IFrameResize makes multiple attempts to talk to the iFrame, so if everything is working then you can safely ignore this error message.

If youre still having problems, or you really want to not ignore the error, then you can try delaying the call to iframeResize() until after the onLoad event of the iframe has fired.

不确定如何在 onLoad 之后加载 iframeResize()

If this does not fix the problem then check x-Frame-Options http header on the server that is sending the iframe content, as this can also block calls to postMessage if set incorrectly.

Google 仅提供两个选项

  • default 不起作用并且

  • allowalljsfiddle 上给我一个错误

    加载时发现无效的 X-Frame-Options 标头 “http://fiddle.jshell.net/_display/?editor_console=true”:“ALLOWALL”不是有效指令。

  • SAMEORIGINGoogle 不接受

我在某处读到错误 Failed to execute 'postMessage' on 'DOMWindow' 可能是因为我的 WordPress 在 http 上运行,而 Google 在 https 上运行。所以我尝试在我的https site 上设置它,但出现同样的错误

iframeResizer.js:800 Failed to execute 'postMessage' on 'DOMWindow': The target origin provided
('https://script.google.com') does not match the recipient window's origin ('https://zz.zustatzdravy.cz').

它还会给出警告信息

iframeResizer.js:142 [iFrameSizer][Host page: iFrameResizer0] IFrame has not responded within
5 seconds. Check iFrameResizer.contentWindow.js has been loaded in iFrame. This message can be
ignored if everything is working, or you can set the warningTimeout option to a higher value
or zero to suppress this warning.

如何检查iFrameResizer.contentWindow.js 是否已加载?

我在正文标签中有这个<script src="https://cdnjs.cloudflare.com/ajax/libs/iframe-resizer/4.2.11/iframeResizer.contentWindow.min.js"></script>

当我直接转到 iframe url 时,我可以看到这个

所以我猜 contentWindow.js 已加载

谁能帮我调整高度?

UPDATE1 GAS 中的 setHeight() 没有帮助 return HtmlService.createTemplateFromFile('index').evaluate().setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL).setHeiht(500)

UPDATE2 最小可重现示例

谷歌文件

  • .gs 代码

这是整个 gs 服务器代码

function doGet() {
  Logger.log("let us start");

  return HtmlService.createTemplateFromFile('index').evaluate().setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL) 
}
  • .html代码

我没有包含整个文本,只是复制并粘贴你能找到的任何内容

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/iframe-resizer/4.2.11/iframeResizer.contentWindow.min.js" integrity="sha512-FOf4suFgz7OrWmBiyyWW48u/+6GaaAFSDHagh2EBu/GH/1+OQSYc0NFGeGeZK0gZ3vuU1ovmzVzD6bxmT4vayg==" crossorigin="anonymous"></script>
    <h2>Povinnosti identifikované osoby</h2>
     <p>Identifikovaná osoba je povinna <strong>podat přihlášku k&nbsp;registraci do 15 dnů</strong> ode dne, kdy se stala identifikovanou osobou. Tuto přihlášku nemusí na rozdíl od plátců DPH podávat elektronicky. Další povinností identifikované osoby je <strong>vést v&nbsp;evidenci pro účely DPH veškeré údaje</strong>, které se vztahují k&nbsp;jejím daňovým povinnostem.</p>
  </body>
</html>

WordPress 文件test WP page

  • 我创建了一个页面并使用了Custom HTML block

里面是这段代码

<iframe id="test" style=" width: 1px;
    min-width: 100%;" src="https://script.google.com/macros/s/AKfycbyCkz_4-s7HTr4nYirkD_UESfObNLy3-DwE0EpWiemmEkSc1F_kev-UzA/exec"></iframe>
    
 
<script>
 iFrameResize({
                log                     : true,                  // Enable console logging
                enablePublicMethods     : true,                  // Enable methods within iframe hosted page
                resizedCallback         : function(messageData){ // Callback fn when resize is received
                    $('p#callback').html(
                        '<b>Frame ID:</b> '    + messageData.iframe.id +
                        ' <b>Height:</b> '     + messageData.height +
                        ' <b>Width:</b> '      + messageData.width + 
                        ' <b>Event type:</b> ' + messageData.type
                    );
                },
                messageCallback         : function(messageData){ // Callback fn when message is received
                    $('p#callback').html(
                        '<b>Frame ID:</b> '    + messageData.iframe.id +
                        ' <b>Message:</b> '    + messageData.message
                    );
                    alert(messageData.message);
                },
                closedCallback         : function(id){ // Callback fn when iFrame is closed
                    $('p#callback').html(
                        '<b>IFrame (</b>'    + id +
                        '<b>) removed from page.</b>'
                    );
                }
            });
</script>
  • 二十一中的functions.php:主题函数

我添加了这段代码来包含插件

/* Custom script with no dependencies, enqueued in the header */
add_action('wp_enqueue_scripts', 'tutsplus_enqueue_custom_js');
function tutsplus_enqueue_custom_js() {
    wp_enqueue_script('custom', 'https://cdnjs.cloudflare.com/ajax/libs/iframe-resizer/4.2.11/iframeResizer.min.js');
}

【问题讨论】:

  • this 有帮助吗?
  • 或者this?
  • 第一个 (setHeight()) 没有帮助,但第二个看起来很有希望。我必须进行更多调查。谢谢
  • @TheMaster 我添加了 Update2。这就是重现问题所需的一切吗?
  • 由于nesting of frames,我相信 contentWindow.js 和主 iframeresizer.js 中的几行需要重写才能找到对方。家长应将消息发送至window.frames[0].frames[0].frames[0],孩子应发送至window.top

标签: javascript html google-apps-script iframe iframe-resizer


【解决方案1】:

编辑:在与@Radek 和@TheMaster 聊天之后,问题似乎是我们需要重定向postMessageAPI 将其消息发送到嵌套iframe 的位置。内部 iframe 都将高度设置为 100%,因此一旦我们更改外部框架的高度,它们就会调整大小。

iframe-resizer 从来没有为这个用例构建过,但也许我们可以稍微修改一下。您需要像现在一样保持通话,但如果我们更改850 行,我们可以重定向消息。继续下面的建议,我认为它需要改变:

iframe.contentWindow.postMessage(msgId + msg, target)

类似于以下内容:

window.gasFrame.postMessage(msgId + msg, target)

现在我们必须获得gasFrame 的值。将以下内容添加到您的 iframe 中。

top.postMessage('gasFrame', '*')

然后在主页上,我们需要延迟启动iframeResize(),直到我们收到该消息。

window.addEventListener("message", (event) => {
  if (event.data === 'gasFrame') {
    window.gasFrame = event.source
    iframeResize({ log: true, checkOrigin: false})
  }
}, false)

我们的下一个问题是浏览器倾向于将 iframe 中内容的高度报告低几个像素。通常我们通过禁用 iframe 上的滚动条来克服这个问题。但是,由于我们有一个无法控制的嵌套 iframe,我们现在无法做到这一点。

唯一的解决方案是在报告的高度上增加一点,以便报告的值总是大于实际高度,我希望在大多数情况下大约 8px 应该没问题,但我已经看到了过去最多 16 像素。

为此,我们可以在 1059 行更改 contentWindow 脚本文件,如下所示。

undefined !== customHeight ? customHeight : getHeight[heightCalcMode]()

并将其更改为

undefined !== customHeight ? customHeight : Number(getHeight[heightCalcMode]()) + 8

如上所述,您可能需要将 8 更改为最适合您网站的值。

【讨论】:

  • 所以,my answer here 显示了 gas webapp 的确切结构。这个 webapp 本身嵌入在 wordpress 站点中。我也知道postMessage can work in a nested context。但我发现很难将您的父 iframe 调整器指向 #userHtmlFrame
  • @TheMaster,而不是“#myIframe”,您可以将直接对象引用传递给 iframe。我以前从未遇到过 GAS,但根据您上面的示例,您可以执行类似 iFrameResize({}, window.top.querySelectorAll('iframe')[0]) 的操作
  • @TheMaster,再深入一点,我不得不承认我不知道您可以跨多个域访问大子 iframe。你指向的那一行我们可以放一个 try/catch 来阻止它出错,但这不会让我们走得更远,因为如果我们不能读取tagName,那么我们也不能设置height
  • 总而言之,如果您在不同的域上有多个级别的 iframe,并且您无法将 JS 添加到其中的任何一个,那么如果没有拥有其他网站。
  • 我更新了 jsFiddle。它现在“工作”了,对不起jsfiddle.net/radek/6qywLr0s/23 我在所有地方都更新了发布的网址,但 jsFiddle
【解决方案2】:

我不是 wordpress 专业人士,所以我不确定你在哪里添加脚本、css 等。但是要让它发挥作用。

由于我没有您的代码,我将尝试从基础开始修复。

  1. 确保您在 wordpress 网站上包含 iframeResizer.min.js 脚本。 (只是简单地了解基础知识)
  2. 在您写问题时,请确保 iframeResizer.contentWindow.min.js 在您的 google 应用程序站点上。 (看起来不错)
  3. 添加小脚本进行初始化,如:&lt;script&gt;iFrameResize({ log : true, enablePublicMethods: true});&lt;/script&gt;(不需要日志,但会向控制台提供一些信息)

我认为您已经完成了这些基本步骤。这通常应该在基本情况下工作,但我认为它不会。最可能的问题是如何为您的应用程序计算高度。 所以接下来尝试更改 heightCalculationMethod 属性以尝试不同的调整大小的方法。

例如,将您的初始化脚本更改为:

<script>iFrameResize({ 
    log : true, 
    enablePublicMethods: true, 
    heightCalculationMethod : 'lowestElement' // This property is added
});</script>

此属性有多个选项,因此请浏览所有选项并尝试其中任何一个有效。

  • 'bodyOffset'
  • 'bodyScroll'
  • 'documentElementOffset'
  • 'documentElementScroll'
  • '最大'
  • '分钟'
  • 'lowestElement'
  • 'taggedElement'

其中一个应该正确更新大小。

如果这不起作用,您可以尝试像这个 stackoverflow 问题一样手动调整大小:make iframe height dynamic based on content inside- JQUERY/Javascript 但这可能需要使用允许的来源等更新标头。

请说这是否可行,否则我会在更多帮助下尝试更新。

【讨论】:

  • 所以我尝试了所有heightCalculationMethod 方法,但都没有奏效。我在发布问题之前尝试的基于动态的高度。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-17
  • 2016-09-09
  • 2014-06-02
  • 2013-01-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多