Frontend Development 13 min read

Comprehensive Guide to Using iframe in Web Frontend: Responsive Sizing, Dynamic Height, Cross‑Domain Communication, and Security

This article provides a detailed tutorial on iframe usage in web front‑end development, covering responsive sizing based on the parent window, dynamic height adjustment via postMessage, handling HTTP/HTTPS mismatches, cross‑origin issues, and security considerations such as X‑Frame‑Options.

Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Comprehensive Guide to Using iframe in Web Frontend: Responsive Sizing, Dynamic Height, Cross‑Domain Communication, and Security

If you are a web front‑end developer, you will inevitably need to work with iframe elements. This guide summarizes the most common scenarios, best practices, and code examples to help you use iframes efficiently and securely.

Responsive iframe based on parent window size

The most frequent requirement is to let an iframe adapt its width and height to the parent container. By binding the :style attribute in Vue and listening to window resize events, you can update the height dynamically while cleaning up listeners to avoid memory leaks.

<template>
  <div class="box" @resize="iframeResize">
    <iframe :src="iframeSrc" :style="{ width: '100%', height: frameHeight + 'px' }" ref="myRef"></iframe>
  </div>
</template>

<script setup>
import { onMounted, onUnmounted, ref, watchEffect } from 'vue';

const myRef = ref(null);
const iframeSrc = 'https:******.com';
const frameHeight = ref(0);

function initHeight() {
  if (myRef.value) {
    frameHeight.value = window.innerHeight;
  }
}

function iframeResize() {
  initHeight();
}

onUnmounted(() => {
  window.removeEventListener('resize', iframeResize);
});

onMounted(() => {
  initHeight();
  window.addEventListener('resize', iframeResize);
});

watchEffect(() => {
  if (myRef.value) {
    initHeight();
  }
});
</script>

<style scoped>
.box {
  position: relative;
  width: 100%;
  height: 100vh;
}
</style>

Dynamic iframe height based on embedded content

When the embedded page’s height is unknown (e.g., a table with variable rows), the child window can send its height to the parent using window.postMessage . The parent listens for the message and sets the iframe’s height accordingly.

Child window code:

<script setup>
    window.onload = function() {
        let height = '想要告诉父窗口的高度';
        if (window.parent && window.parent.postMessage) {
            window.parent.postMessage({height: height}, '*');
        }
    };
</script>

Parent window code:

<template>
  <div>
    <iframe :src="iframeSrc" ref="myRef"></iframe>
  </div>
</template>

<script setup>
import { onMounted, ref } from 'vue';

const iframeSrc = 'https:******.com';
const myRef = ref(null);

onMounted(() => {
  window.addEventListener('message', iframeMessage);
});

const iframeMessage = (event) => {
  if (event.origin !== 'https:******.com') return;
  const newHeight = event.data.height;
  if (newHeight && myRef.value) {
    myRef.value.style.height = `${newHeight}px`;
  }
};
</script>

Iframe embedding without login

The author references a separate article that explains how to achieve seamless login‑free embedding of pages inside an iframe.

HTTP cannot embed HTTPS

Embedding an HTTP page into an HTTPS page is blocked by modern browsers for security reasons. The two reliable solutions are converting the HTTP resource to HTTPS or using a proxy service.

Method 1: Convert HTTP to HTTPS (recommended)

Obtain an SSL certificate and configure the server (example shown for Nginx) to redirect all HTTP traffic to HTTPS.

server {
  listen 80;
  return 301 https://$host$request_uri;
  server_name ****.com www.****.com;
}

server {
  listen 443 ssl;
  server_name ****.com www.****.com;
  ssl_certificate /etc/lets/live/****.com/fullchain.pem;
  ssl_certificate_key /etc/lets/live/****.com/privkey.pem;

  location / {
      index index.html index.htm;
      root /var/w/html;
  }
}

Method 2: Use a proxy service

Set up a simple Node.js proxy that forwards requests to the target HTTP site over HTTPS.

npm init -y
npm install express http-proxy
const express = require('express');
const fs = require('fs');
const https = require('https');
const http = require('http');
const httpProxy = require('http-proxy');

const app = express();
const proxy = httpProxy.createProxyServer();
const port = 3000;

const options = {
  key: fs.readFileSync('/etc/lets/live/proxy.****.com/privkey.pem'),
  cert: fs.readFileSync('/etc/lets/live/proxy.****.com/fullchain.pem')
};

app.all('/proxy/*', (req, res) => {
  const targetUrl = `http://${req.params[0]}`;
  proxy.web(req, res, { target: targetUrl }, (error) => {
    res.status(500).send('Proxy request failed');
  });
});

const server = https.createServer(options, app);
server.listen(port, () => {
  console.log(`HTTPS`);
});

Cross‑origin issues

When the iframe and its parent are on different origins, the browser’s same‑origin policy restricts access to the iframe’s DOM and cookies. Several solutions are provided.

1. Use window.postMessage for cross‑origin communication

The parent registers a message listener, and the child sends data via postMessage . Remember to add and remove listeners appropriately.

<template>
  <div>
    <iframe :src="iframeSrc" ref="iframeRef" @load="onIframeLoad" style="width: 100%; height: 400px;"></iframe>
    <button @click="sendMessage">发送消息</button>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue';

onMounted(() => {
  window.addEventListener('message', handleMessage);
  return () => {
    window.removeEventListener('message', handleMessage);
  };
});

const iframeSrc = 'http://***.com';
const iframeRef = ref(null);

const onIframeLoad = () => {
  window.addEventListener('message', handleMessage);
};

const sendMessage = () => {
  const iframe = iframeRef.value;
  if (iframe.contentWindow) {
    iframe.contentWindow.postMessage('Hello!', 'http://***.com');
  }
};

const handleMessage = (event) => {
  if (event.origin !== 'http://***.com') return;
  console.log(event.data);
};
</script>

2. Use document.domain for sub‑domain sharing

Set the same top‑level domain on both pages to allow them to interact.

<template>
  <div>
    <iframe :src="iframeSrc" @load="onIframeLoad" ref="iframeRef"></iframe>
  </div>
</template>

<script setup>
import { ref } from 'vue';

document.domain = 'tty.com';

const iframeRef = ref(null);
const iframeSrc = 'http://b.tty.com';

const onIframeLoad = () => {
  const iframe = iframeRef.value;
  if (iframe.contentWindow) {
    iframe.contentWindow.document.domain = 'tty.com';
  }
};
</script>

3. Use CORS headers

Configure the server (example with Nginx) to send Access-Control-Allow-Origin so that the iframe can be accessed from other origins.

http {
  server {
      listen 80;
      server_name yourdomain.com;

      location /iframe-proxy/ {
          add_header Access-Control-Allow-Origin *;
      }
  }
}

4. Nginx reverse proxy

Proxy the iframe request through Nginx to bypass cross‑origin restrictions.

http {
  server {
      listen 80;
      server_name yourdomain.com;

      location /iframe-proxy/ {
          proxy_pass http://tty.com/;
      }
  }
}

Iframe connection refused (X‑Frame‑Options)

If the target page sends an X-Frame-Options header that disallows embedding, the iframe will fail to load. This requires cooperation from the backend to adjust or remove that header.

Conclusion

The article summarizes common iframe scenarios—responsive sizing, dynamic height, protocol mismatches, cross‑origin communication, and security restrictions—providing practical code snippets and configuration examples for front‑end developers.

proxyvueCross-Originnginxweb securityResponsive Designiframe
Rare Earth Juejin Tech Community
Written by

Rare Earth Juejin Tech Community

Juejin, a tech community that helps developers grow.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.