'Is it possible to add a property to an iframe window object before it loads such that the value is available to scripts in the frame?
I would like to add a property to an iframe's window before the page loads its content. I would like it set so that scripts loaded on the source have access to that property.
As an example, this is what I am attempting to do:
<!- index.html ->
<body>
<script type="module">
const iframe = document.createElement('iframe')
iframe.src = 'about:blank'
const onLoad1 = new Promise(res => iframe.onload = res)
document.body.appendChild(iframe)
await onLoad1
iframe.contentWindow.foo = 'something'
console.log(iframe.contentWindow.foo)
const onLoad2 = new Promise(res => iframe.onload = res)
iframe.src = 'frame.html' // same origin
await onLoad2
console.log(iframe.contentWindow.foo) // currently undefined
</script>
</body>
<!- frame.html ->
<script>
console.log(window.foo) // currently undefined
</script>
I realise the contentWindow is a new Window because re-assigning the src property triggers a new page load.
I was hopeful that travelling from about:blank to a same origin path would grant me special powers persist properties set on the window but that wasn't the case.
Currently (what I am trying to avoid), I am resorting to emitting a custom event and capturing that asynchronously within the frame. This is a cumbersome dance and not ideal for situations where values must be known synchronously.
<!- index.html ->
<body>
<script type="module">
const iframe = document.createElement('iframe')
iframe.src = 'frame.html'
const onLoad1 = new Promise(res => iframe.onload = res)
document.body.appendChild(iframe)
await onLoad1
function sendValue() {
iframe.contentWindow.dispatchEvent(
new CustomEvent('custom:onload', { detail: 'foo' }))
}
iframe.contentWindow.addEventListener('custom:request:onload', sendValue)
sendValue()
</script>
</body>
<!- frame.html ->
<body>
<script async type="module">
const onfoo = new Promise(
res => window.addEventListener('custom:request:onload', e => res(e.detail))
window.dispatchEvent(new CustomEvent('custom:request:onload'))
</script>
</body>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
