Skip to main content

How to Resolve "DOMException: Blocked a frame with origin from accessing a cross-origin frame" Error in JavaScript

The error DOMException: Blocked a frame with origin from accessing a cross-origin frame is a security measure built into all modern browsers. It occurs when a script on one page tries to directly access the content of an <iframe> that was loaded from a different origin.

This guide will explain what this error means, why it exists, and walk you through the modern, secure method for communicating between a page and a cross-origin <iframe> using the window.postMessage() API.

The Core Problem: The Same-Origin Policy

The Same-Origin Policy is a fundamental security feature in web browsers. It prevents a script on one page from accessing the DOM and data of another page unless they share the same origin. This is designed to stop malicious sites from performing dangerous actions.

For example, without this policy, a malicious site could:

  1. Load your bank's website in an invisible <iframe>.
  2. If you were logged in, the script could reach into the <iframe>, read your account balance, and even click the "transfer funds" button on your behalf.

The browser blocks this by default, which is what triggers the "Blocked a frame..." error.

What is a "Cross-Origin" Frame?

Two URLs are considered to have a different origin if they differ in any of these three parts:

  1. Protocol (e.g., http:// vs. https://)
  2. Hostname (e.g., www.example.com vs. sub.example.com or www.google.com)
  3. Port (e.g., example.com:3000 vs. example.com:8080)

If a page at https://my-app.com tries to access an <iframe> whose src is https://third-party.com, the origins are different, and direct access will be blocked.

The window.postMessage() API is the standard, secure way to enable communication between a page and a cross-origin <iframe> when you have control over the code on both sides. It allows the two windows to send and receive messages safely without violating the Same-Origin Policy.

How to Send a Message to an <iframe>

The parent page (the one containing the <iframe>) is responsible for sending the message.

The logic:

  1. Get a reference to the <iframe> element.
  2. Access its contentWindow property.
  3. Call the .postMessage() method on the contentWindow.

The solution is to use the parent page code:

// Get a reference to the iframe element
const iframe = document.getElementById('my-iframe');

const messageData = {
action: 'update-user',
userId: 123,
newName: 'Alice',
};

// Send the message to the iframe
// The second argument is the target origin, for security.
iframe.contentWindow.postMessage(messageData, 'https://iframe-domain.com');

where:

  • messageData: The data you want to send. It can be any object, string, or other serializable data.
  • 'https://iframe-domain.com': The target origin. This is a crucial security measure. It ensures that your message is only sent if the <iframe> is currently loaded from the specified origin. For development, you can use '*', but in production, you should always use the specific origin.

How to Receive a Message Inside an <iframe>

The page loaded inside the <iframe> must set up an event listener to receive the message.

The logic:

  1. Add a 'message' event listener to the window object.
  2. Inside the listener, always verify the event.origin to ensure the message came from a trusted source.
  3. If the origin is trusted, you can safely use the data from event.data.

The solution is to use the code inside the <iframe>:

window.addEventListener('message', (event) => {
// IMPORTANT: Always verify the origin of the message!
if (event.origin !== 'https://parent-domain.com') {
// If the origin is not trusted, do nothing.
return;
}

// event.data contains the data sent from the parent.
const receivedData = event.data;
console.log('Message received from parent:', receivedData);

// Now, you can act on the data.
if (receivedData.action === 'update-user') {
// ... update the user with the given ID ...
}
});

Insecure Workarounds (and Why to Avoid Them)

You may see suggestions online to disable the Same-Origin Policy in your browser.

  • Method: Launching Chrome with a command-line flag like --disable-web-security.
  • Why you should not do this: This is extremely dangerous. It turns off a fundamental security feature of your browser, making you vulnerable to cross-site request forgery (CSRF) and other attacks from any website you visit. This should only ever be used for temporary, local testing by experienced developers, and never for general browsing.

Conclusion

The "Blocked a frame with origin" error is not a bug to be bypassed, but a critical security feature to be respected.

  • Direct DOM access across different origins is and should be blocked by the browser's Same-Origin Policy.
  • The correct and professional way to communicate between a page and a cross-origin <iframe> is with the window.postMessage() API.
  • When using postMessage(), always specify the target origin when sending and verify the event's origin when receiving to ensure secure communication.