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.
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.
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.