I’m trying to use a bookmarlet to get a value from an iframe, which is loaded from another domain. I’m getting x-origin errors, but I don’t need to communicate "between" the frames, I just need to read data from the iframe, like I would from the parent.
I do not have access to modify either the parent or child frame. I cannot load the child iframe alone either.
I recreated a super simplified version of the structure I’m working with.
Parent page
url1.com/parent.html
<body>
<h1>Parent Title</h1>
<iframe src="url2.com/child.html" id="xoFrame"></iframe>
</body>
Child iframe
url2.com/child.html
<body>
<h1>Child Iframe Title</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus congue est vitae mauris pulvinar hendrerit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.</p>
<a class="button" href="#">Child Frame Button</a>
<footer>© Footer Text 2048</footer>
</body>
I found a "solution" that would work for me as I would only be running it on my computer. It involves running Chrome with a few flags. However, it didn’t change anything. Running Chrome 109.
chrome.exe --disable-web-security --disable-gpu --disable-features=IsolateOrigins,site-per-process --user-data-dir="C://chrome-dev"
For the purpose of this test, I’m trying to get the innerText
of a.button
inside the iframe. I created four different bookmarlets to illustrate my point.
Bookmarklet 1
console.log('TEST 1. TRYING TO ACCESS PARENT > H1:');
console.log(document.querySelector('h1').innerText);
Result 1
TEST 1. TRYING TO ACCESS PARENT > H1:
Parent Title
Bookmarklet 2
console.log('TEST 2. TRYING TO ACCESS CHILD IFRAME > A.BUTTON DIRECTLY');
console.log(document.querySelector('a.button').innerText);
Result 2
TEST 2. TRYING TO ACCESS CHILD IFRAME > A.BUTTON DIRECTLY
Uncaught TypeError: Cannot read properties of null (reading 'innerText')
at <anonymous>:1:132
at <anonymous>:1:145
Bookmarklet 3
console.log('TEST 3. TRYING TO ACCESS IFRAME > CONTENTWINDOW');
console.log(document.getElementById('xoFrame').contentWindow);
Result 3
TEST 3. TRYING TO ACCESS IFRAME > CONTENTWINDOW
global {window: global, self: global, location: {…}, closed: false, frames: global, …}
Bookmarklet 4
console.log('TEST 4. TRYING TO ACCESS IFRAME > CONTENTWINDOW > DOCUMENT');
console.log(document.getElementById('xoFrame').contentWindow.document);
Result 4
TEST 4. TRYING TO ACCESS IFRAME > CONTENTWINDOW > DOCUMENT
Uncaught DOMException: Blocked a frame with origin "url1.com" from accessing a cross-origin frame.
at <anonymous>:1:147
at <anonymous>:1:159
All I need is a solution that would return Child Frame Button
in this scenario.
2
Answers
After posting this, I went and looked back at starting Chrome with web security disabled. This works with Chrome 109.
Make sure ALL instances of Chrome are closed before running it.
Bookmarklet 5
Result 5
You can’t.
Bookmarklets run in the context of the top level frame.
They are subject to the same cross-origin security restrictions as any other JS running in that frame.