Last updated: Apr 4, 2024
Reading timeยท4 min
Depending on your browser, the error might be named differently:
Uncaught DOMException: Blocked a frame with origin from accessing a cross-origin frame.
Uncaught SecurityError: Blocked a frame with origin from accessing a frame with origin
The error "DOMException: Blocked a frame with origin from accessing a
cross-origin frame" occurs when you load an <iframe>
in HTML and try to access
the elements within it using JavaScript.
You can't directly access an <iframe>
with a different origin as that could
lead to security vulnerabilities.
iframe
and access the HTML, then you could easily check if the user is logged in or not and retrieve potentially sensitive information.This would make phishing attacks much easier than they currently are.
There are a couple of ways to get around this, e.g. using window.postMessage
or disabling the same-origin policy in your browser.
The same-origin policy causes browsers to block scripts that are trying to access an iframe with a different origin.
For the origin to be considered different, at least one of the following 3 components has to be different:
protocol://hostname:port/path
For example, suppose that the URL from which you are trying to access resources is the following:
https://www.example.com/articles
You would then be able to access the DOM in the following URLs using an
iframe
.
https://www.example.com/users
https://www.example.com/any/other/path
https://www.example.com
https://www.example.com:80
(Port 80 is the default)However, you wouldn't be able to access the following URLs:
http://www.example.com/users
- (Different protocol)https://www.example.com:3000/users
- (Different port)https://subdomain.example.com/users
- (Different hostname)http://gmail.com/users?q=bobby+hadz
- (Different protocol and hostname)window.postMessage()
method to get around thisIf you own or have access to both pages, you can get around the same-origin policy by using the window.postMessage() method.
The method safely enables cross-origin communication between Window
objects,
e.g.:
For example, you could add the following code to your main page.
const frame = document.getElementById('YOUR-IFRAME-ID'); const data = { id: 1, name: 'bobby hadz', salary: 1500, }; frame.contentWindow.postMessage( // ๐๏ธ data you want to pass to the other page data, 'https://YOUR-OTHER-PAGE.com', );
The first argument we passed to postMessage()
is the data we want to send over
to the other page.
The data
variable doesn't have to be an object, it could be a simple string,
an integer or any other value.
The second argument we passed to postMessage()
can be a string containing an
asterisk if you want to indicate that any origin can be the destination of the
message.
frame.contentWindow.postMessage( // ๐๏ธ data you want to pass to the other page data, // ๐๏ธ no preference about the origin of the destination '*', );
However, it is usually better to be specific to avoid leaking data to other sites.
Then, in your <iframe>
that is contained in the main page, your could would
look similar to the following.
window.addEventListener('message', event => { // ๐๏ธ check the origin of the data if (event.origin === 'https://YOUR-FIRST-PAGE.com') { // If this runs, the data was sent from your site // The data sent with postMessage() is accessed via // event.data console.log(event.data); } else { // If this runs, the data was NOT sent from your site // Make sure to not use this data // You can remove the `else` statement return; } });
The event.origin
property enables you to check if the data was sent from your
own site.
If the data was sent from your site, then you can access it using event.data
.
If it wasn't sent from your site, then you shouldn't use it.
This approach can be used in both directions.
For example, you could also:
You could also disable the same-origin policy to get around the error.
This stackoverflow page has instructions on how to disable the same-origin policy in Chrome.
As previously, the same-origin policy causes browsers to block scripts that are trying to access an iframe with a different origin.
For the origin to be considered different, at least one of the following 3 components has to be different:
protocol://hostname:port/path
However, disabling the same-origin policy is not advisable and only affects your browser.
This should only be used for development purposes.
Another thing you can try is to use a different browser and see if you still get the error.
For example, if you get the error when using Chrome, try to use Firefox.
document.domain
Something you can try if both pages run on the same domain but different ports
(e.g. http://localhost:3000
and http://localhost:5000
) is to set the
document.domain
property.
Each window has to set its domain to the shared origin (localhost
in the
example).
document.domain = 'localhost';
This should also work if the pages have different subdomains. For example:
https://abc.example.com
https://xyz.example.com
Then, each window has to set its domain as follows.
document.domain = 'example.com';
Most browsers ignore the hostname difference and enable you to treat the pages as if they came from the same origin.
const frame = document.getElementById('YOUR-IFRAME-ID'); frame.contentWindow.document.body.classList.add('my-class');
If this doesn't work in Chrome, try using a different browser, e.g. Firefox.
However, note that the property has been deprecated.
You can learn more about the related topics by checking out the following tutorials: