ใช้ window.top หรือ window.parent เพื่อเข้าถึงฟังก์ชันในหน้าผู้ปกครอง (Parent Window) จาก iframe
ตัวอย่างจากบทความ
<!DOCTYPE html>
<html>
<body>
<script>
function display() {
alert("Hello World!");
}
</script>
<iframe id="myFrame">
<a onclick="window.top.display();" href="#">Click</a>
</iframe>
</body>
</html>
window.top vs window.parent
| Property | คำอธิบาย |
|---|---|
window.top | หน้าต่างบนสุด (Top-most window) - ข้ามหลายชั้น iframe ได้ |
window.parent | หน้าต่างพ่อโดยตรง (Immediate parent) - ขึ้น 1 ระดับ |
window.self | ตัวเอง (Current window) |
// ใน iframe ชั้นที่ 2 (nested iframe) window.parent; // iframe ชั้นที่ 1 window.top; // Main window (ชั้นบนสุด) window.self; // iframe ชั้นที่ 2 (ตัวเอง)
ข้อจำกัดด้านความปลอดภัย (Same-Origin Policy)
ทำงานได้ก็ต่อเมื่อ: Parent และ iframe อยู่ใน Origin เดียวกัน (Protocol, Domain, Port เหมือนกัน)
// Cross-origin - จะได้ SecurityError // Parent: https://example.com // Iframe: https://other.com // iframe content: window.top.myFunction(); // ❌ Blocked by CORS
วิธีแก้ Cross-Origin: postMessage()
Parent Window (Receiver)
<script>
function handleMessage(event) {
// ตรวจสอบ origin เพื่อความปลอดภัย
if (event.origin !== 'https://trusted-child.com') return;
if (event.data.type === 'CALL_FUNCTION') {
const { funcName, args } = event.data;
if (typeof window[funcName] === 'function') {
window[funcName](...args);
}
}
}
window.addEventListener('message', handleMessage);
</script>
<iframe src="https://trusted-child.com/child.html"></iframe>
Iframe (Sender)
<script>
function callParent(funcName, ...args) {
window.parent.postMessage({
type: 'CALL_FUNCTION',
funcName,
args
}, 'https://parent-origin.com'); // ระบุ target origin
}
// ใช้งาน
document.getElementById('btn').addEventListener('click', () => {
callParent('display', 'Hello from iframe!');
});
</script>
กรณี Same-Origin (เรียกตรงได้)
// ใน iframe (same origin) // เรียกฟังก์ชัน global window.top.myGlobalFunction(); // เรียกเมธอดใน object window.parent.MyModule.myMethod(); // เรียกด้วยชื่อสตริง window.top['functionName']();
Best Practices
- ตรวจสอบ
event.originเสมอใน postMessage - ส่ง
targetOriginไม่ใช่*ใน postMessage - Define ชัดเจน API (message types) ระหว่าง parent-child
- หลีกเลี่ยงการเรียกฟังก์ชันโดยตรงข้าม origin