I have been reading a lot of the answers here but nearly everyone gave some sort of cross-origin frame block.
Example error:
Uncaught DOMException: Blocked a frame with origin "null" fromaccessing a cross-origin frame.
The same for the answers in a related thread:
Make iframe automatically adjust height according to the contents without using scrollbar?
I do not want to use a third party library like iFrame Resizer
or similar library either.
The answer from @ChrisJacob is close but I'm missing a complete working example and not only links. @Selvamani and @latitov are good complements as well.
https://stackoverflow.com/a/3219970/3850405
I'm using width="100%"
for the iframe
but the code can be modified to work with width as well.
This is how I solved setting a custom height for the iframe
:
Embedded iframe
:
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8" /><meta name="description" content="Web site" /><title>Test with embedded iframe</title></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><iframe id="ifrm" src="https://localhost:44335/package/details?key=123" width="100%"></iframe><script type="text/javascript"> window.addEventListener('message', receiveMessage, false); function receiveMessage(evt) { console.log("Got message: " + JSON.stringify(evt.data) +" from origin: " + evt.origin); // Do we trust the sender of this message? if (evt.origin !== "https://localhost:44335") { return; } if (evt.data.type === "frame-resized") { document.getElementById("ifrm").style.height = evt.data.value +"px"; } }</script></body></html>
iframe source
, example from Create React App
but only HTML
and JS
is used.
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8" /><meta name="description" content="Web site created using create-react-app" /><title>React App</title></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script type="text/javascript"> //Don't run unless in an iframe if (self !== top) { var rootHeight; setInterval(function () { var rootElement = document.getElementById("root"); if (rootElement) { var currentRootHeight = rootElement.offsetHeight; //Only send values if height has changed since last time if (rootHeight !== currentRootHeight) { //postMessage to set iframe height window.parent.postMessage({ "type": "frame-resized", "value": currentRootHeight }, '*'); rootHeight = currentRootHeight; } } } , 1000); }</script></body></html>
The code with setInterval
can of course be modified but it works really well with dynamic content. setInterval
only activates if the content is embedded in a iframe
and postMessage
only sends a message when height has changed.
You can read more about Window.postMessage()
here but the description fits very good in what we want to achieve:
The window.postMessage() method safely enables cross-origincommunication between Window objects; e.g., between a page and apop-up that it spawned, or between a page and an iframe embeddedwithin it.
Normally, scripts on different pages are allowed to access each otherif and only if the pages they originate from share the same protocol,port number, and host (also known as the "same-origin policy").window.postMessage() provides a controlled mechanism to securelycircumvent this restriction (if used properly).
https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage