You need to access the parent page's document
to be able to get the <iframe>
, in the current frame's document
, that element isn't accessible.
If the page in the iframe is from the same domain as the main page, then you can find that parent document through window.parent.document
, but this will work only if both pages share the same origin.
So the best might be to embrace directly a more bullet-proof solution that will work even in cross-origin iframes: use the postMessage
API.
From your iframe you can send a message to the parent window letting it know that it's ready to be reloaded. On the parent page, you'd listen for such message and reload the source iframe. Since this event receives the source
WindowProxy object that is also available as iframe.contentWindow
, we don't even need to set a name
attribute anymore:
window.addEventListener("message", (evt) => {
if (evt.data === "confirmation" /* && evt.origin === theURL */) {
// search for the source <iframe>
const frameElement = [...document.querySelectorAll("iframe")]
.find((elem) => elem.contentWindow === evt.source);
if (frameElement) {
// I use srdoc in this Snippet but you'd use .src
frameElement.srcdoc = frameElement.srcdoc;
}
}
});
<iframe srcdoc="
<h1>first page</h1>
<a>go to confirmation page</a>
<script>
// the content of the second iframe
const confirmContent = `<!DOCTYPE html>
<h1>confirmed</h1>
<h2>You will be redirected in a few seconds</h2>
<script>
setTimeout(() => {
parent.postMessage('confirmation', '*');
}, 2000);
<\/script>`;
document.querySelector('a').href = 'data:text/html,' + encodeURIComponent(confirmContent);
</script>
"></iframe>
To clarify a bit this example since StackSnippets force us to use some weird workarounds, you'd have in the parent page:
<iframe src="frame.html"></iframe>
<script>
window.addEventListener("message", (evt) => {
if (evt.data === "confirmation" /* && evt.origin === theURL */) {
// search for the source <iframe>
const frameElement = [...document.querySelectorAll("iframe")]
.find((elem) => elem.contentWindow === evt.source);
if (frameElement) {
frameElement.src = frameElement.src;
}
}
});
</script>
Then in iframe.html:
<h1>first page</h1>
<a href="https://example.com/confirmation.html">go to confirmation page</a>
and in confirmation.html:
<h1>confirmed</h1>
<h2>You will be redirected in a few seconds</h2>
<script>
setTimeout(() => {
parent.postMessage("confirmation", "*");
}, 2000);
<\/script>