Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> JavaScript

วิธีเรียกฟังก์ชัน Parent Window จาก iframe ใน JavaScript

ใช้ 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