简体   繁体   中英

How to change height of GAS iframe (in WordPress) using iframe-resizer

I want to add iframe of my Google Application Script Web to WordPress site. I want to get rid of the scroll bar. See the pic.

在此处输入图像描述

Not sure if the iframe-resizer does not work because of this error message

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').

From iframe-resizer troubleshooting page looks like this error does not have to be an issue that

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.

not sure how I can load iframeResize() after the onLoad

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 offers only two options在此处输入图像描述

  • default does not work and

  • allowall gives me an error on jsfiddle

    Invalid X-Frame-Options header was found when loading “http://fiddle.jshell.net/_display/?editor_console=true”: “ALLOWALL” is not a valid directive.

  • SAMEORIGIN Google does not accept

I read somewhere that the error Failed to execute 'postMessage' on 'DOMWindow' could be because my WordPress runs on http but Google on https. So I tried to se it up on my https site but with the same error

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').

it also gives a warning message

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.

How can I check that iFrameResizer.contentWindow.js was loaded?

I have this in body tag <script src="https://cdnjs.cloudflare.com/ajax/libs/iframe-resizer/4.2.11/iframeResizer.contentWindow.min.js"></script>

and when I go directly to the iframe url then I can see this在此处输入图像描述

So I guess the contentWindow.js was loaded

Anyone could help me to make the hight resize?

UPDATE1 setHeight() in GAS did not help return HtmlService.createTemplateFromFile('index').evaluate().setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL).setHeiht(500)

UPDATE2 minimal reproducible examples

Google files

  • .gs code

this is the whole gs server code

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

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

I did not include the whole text, just copy and paste anything you can find

<!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 files test WP page

  • I created a page and used Custom HTML block .

Inside is this code

<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 inside Twenty Twenty-One: Theme Functions

I added this code to include the plugin

/* 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');
}

Edit: After chatting with @Radek and @TheMaster it seems the problem is that we need to redirect where the postMessageAPI sends its message to a nested iframe. The inner iframe all have height set to 100% so they will resize once we change the outer frame's height.

Iframe-resizer was never built for this use case, but maybe we can hack it a little. You need to keep the call as you have it now, but if we change line 850 we could redirect the message. Going on what was suggested below I think it would need to change from:

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

to something along the lines of:

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

Now we have to get a value for gasFrame . Add the following into your iframe.

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

Then on the main page we need to delay kicking off iframeResize() until we receive that message.

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

Our next problem is that browsers tend to under report the height of the content in the iframe by a few pixels. Normally we overcome this by disabling the scroll bars on the iframe. However, as we have a nested iframe that we have no control over we are now unable to do that.

The only solution to this is going to be to add a little bit to the reported height so that reported value is alway more than the actual height, I would expect in most cases around 8px should be ok, but I have seen it out by as much as 16px in the past.

To do this we can change the contentWindow script file as follows at line 1059 you will see the following.

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

and change it to

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

As I said above you may need to change 8 to a value that works best for your site.

I am no wordpress pro so I am not sure where you add scripts, css and such. But to get this working.

Since I don't have your code I will try go through steps from basics to fix.

  1. Make sure you have the iframeResizer.min.js script included on the wordpress site. (just getting basics out of the way)
  2. As you write in your question make sure that the iframeResizer.contentWindow.min.js is on your google application site. (looks good as you write)
  3. Add small script to initialize like: <script>iFrameResize({ log: true, enablePublicMethods: true});</script> (Log not needed but gives some info to console)

I think you have these basic steps done. This normally should work in base cases but I assume it does not. The most likely issue is how height is calculated for your application. So next try change the heightCalculationMethod property to try different methods of resizing.

For example change your init script to:

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

There are multiple options for this property so go through them all and try if any of them work.

  • 'bodyOffset'
  • 'bodyScroll'
  • 'documentElementOffset'
  • 'documentElementScroll'
  • 'max'
  • 'min'
  • 'lowestElement'
  • 'taggedElement'

One of these should update the size correctly.

If this does not work you could try doing the resize manually like this stackoverflow question: make iframe height dynamic based on content inside- JQUERY/Javascript But this might requere updating header with allowed origins and such.

Pls say if this work or I will try update with more help.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM