CONTENT:
### GENERAL REVIEWS ###
⭐ ⭐
by Chris Coyier | January 5, 2010
doc
⭐ ⭐
doc
### SAME DOMAIN SOLUTIONS ###
- use JS to just set the height of iframe to be the same height as the target page
- the iframe must have an ID and a NAME
- will not work if the iframe contains content from another domain due to the Same Origin Policy
- see cross-domain solutions below
<iframe id="some_id" name="some_name" src="some_page.html" style="border: 1px solid silver; width:600px" onload="setIframeHeight(this.id)"></iframe>
...
try {
var f = document.getElementById("myiframeid");
// IE opt. for bing/msn needs a bit added or scrollbar appears
if (f.contentDocument) {
f.height = f.contentDocument.documentElement.scrollHeight + 30; //FF 3.0.11, Opera 9.63, and Chrome
} else {
f.height = f.contentWindow.document.body.scrollHeight + 30; //IE6, IE7 and Chrome
}
alert('This iframe should be ' + f.hight + ' pixels in height to avoid scrolling.');
}
catch (err) {
alert('Err: ' + err.message);
window.status = err.message;
}
- jQuery plugin to set the height of an iframe to its contents height
source
- good for:
- allowing cross SUBdomain window access
- you would be allowed to exectue javascript from an iframe sourced on a subdomain on a page sourced on the main domain;
- will not allow you to change the document.domain to a completely alien domain.
- works in all relevant browsers
- if both documents are on the same top level domain, are using the same protocol and you can add the following line of JavaScript to the page in the iframe:
// on http://sub.site.com
document.domain = "site.com";
// now the subdomain has the same permissions for access
### CROSS DOMAIN SOLUTIONS ###
- overcome cross domain security restrictions
- needs access to the iframe server to paste code
I. PostMessage
II. JSONP
III. CORS
IV. Window.name
V. Server side proxies
VI. Crazy iFrame Hacks (iFrame INSIDE iFrame trick)
- just pass messages between window objects
- safe because both pages have to know about it
- good for:
- passing events along from one window to the other
- initializing the state of a new window
- synchronizing two pages
- FF 3+, IE 8+, Chrome 1+, Safari 4+
Cross-Domain Messaging With postMessage
doc source demo
Cross Domain IFrame communications throuth PostMessage
doc
// 1) post message syntax
otherWindow.postMessage(message, targetOrigin);
...
// 2) handle the message event in the otherWindow
function receiveMessage(event) {
if (event.origin !== "http://example.org:8080")
return;
}
The iframe page:
<!DOCTYPE html>
<head>
</head>
<body onload="parent.postMessage(document.body.scrollHeight, 'http://target.domain.com');">
<h3>Got post?</h3>
<p>Lots of stuff here which will be inside the iframe.</p>
</body>
</html>
The parent page which contains the iframe (and would like to know its height):
<script type="text/javascript">
function resizeCrossDomainIframe(id, other_domain) {
var iframe = document.getElementById(id);
window.addEventListener('message', function(event) {
if (event.origin !== other_domain) return; // only accept messages from the specified domain
if (isNaN(event.data)) return; // only accept something which can be parsed as a number
var height = parseInt(event.data) + 32; // add some extra height to avoid scrollbar
iframe.height = height + "px";
}, false);
}
</script>
<iframe src='http://example.com/page_containing_iframe.html' id="my_iframe" onload="resizeCrossDomainIframe('my_iframe', 'http://example.com');">
</iframe>
- cross domain sizing iframes to content with support for window resizing
- uses HTML5 postMessage to keep an iFrame sized to it's content
- uses MutationObserver to detect changes to the content
source
- a library that will use postMessage first and then a series of different techniques based on which browser you use, but with normalized syntax
- a good cross-browser solution (PostMessage, window.name, flash fallback)
- used by a lot of websites, including Twitter and Disqus
source doc doc
example - How To Set Iframe Container Height From Remote Domain using easyXDM
example
var socket = new easyXDM.Socket({
...,
onMessage: funciton (message, origin) {
alert(message);
}
});
- JavaScript Object Notation with Padding (JSONP)
- a subset of JavaScript with some extra rules
- non-exutable - just for data
- good for:
- data passing
- RESTful APIs
- 1-(way/time)-ish cross domain communication
- hacking - you are adding a script tag to the target domain. They can send anything back, even regular javascript (XSS attack). So you really have to trust them not to do bad stuff or become hacked. Any other webpage can add the same script-tag, and steal the data, so never ever use JSONP for private data.
// 1) create a callback function that accepts some data
function jsonpCallback(data) {
console.log(data);
}
// 2) include a script with a hint of what your function is called
<script src="http://site.com?cb=jsonpCallback"></script>
// 3) output a script that calls the function and passes in the necessary data
jsonpCallback ({
"this" : "is",
"super" : "awesome",
"data" : "forealz"
});
- Cross-Origin Resource Sharing (CORS) - W3C Working Draft that defines how he browser and server must communicate when accessing sources across origins.
- CORS sends along an extra header - " Origin: http://site.com "
- IE 8+, FF 3.5+, Safari 4+, Chrome
- good for:
- not working on 40% of the internet (IE 10+)
- creaiting an extra http request (usually only once)
- custom grouping options
- finer grain control over what's accessible
- Straight Up. Cross Domain XHR
// syntax
function createCORSRequest (method, url) {
var xhr = new XMLHttpRequst();
if ("withCredentials" in xhr){
xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined") {
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
xhr = null;
}
return xhr;
}
// use our new method or lose it
var req = createCORSRequest("get", "http://site.com/");
if (req) {
req.onload = function() {
// do something with req.responseText
};
req.send();
}
// your server must send back another, saying it's Ok:
// Access-Control-Allow-Origin: http://site.com
// OR
// Access-Control-Allow-Origin: *
// [doc](http://sv-igor.com/ru/htaccess/82-x-frame-options.html)
<?php
header('X-Frame-Options: GOFORIT');
header('Access-Control-Allow-Origin: http://site.com');
header('Access-Control-Allow-Credentials: true');
?>
// * wont work in FF w/ Allow-Credentials
//if you dont need Allow-Credentials, * seems to work
header('Access-Control-Allow-Origin: http://www.example.com');
//if you need cookies or login etc
header('Access-Control-Allow-Credentials: true');
if ($this->getRequestMethod() == 'OPTIONS')
{
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
header('Access-Control-Max-Age: 604800');
//if you need special headers
header('Access-Control-Allow-Headers: x-requested-with');
exit(0);
}
- Superhacky but safer than JSONP
- works everywhere relevant
// in the child window
window.name = '{"secret": "message"}';
// in the parent window
var secret = JSON.parse(childWindow.name);
- pretty simple concept, only slightly more difficult to implement
doc
- a window can read and write properties of an iframe if it's on the same domain - EVEN IF it's inside of another iframe that isn't on the same domain!
- a browser hack which allows us to skirt the same origin policy - there is always a chance that it will stop working one day with a browser update (this is still a hack).
- good for:
- works at varying levels of success via some slightly different methods in all relevant browsers
- unfortunately often a best choice for something that works everywhere
www.foo.com/home.html, which iframes
|-> www.bar.net/framed.html, which iframes
|-> www.foo.com/helper.html
Communication options for each page: framed.html can send messages to helper.html (iframed) but not home.html (child can't communicate cross-domain with parent).
The key here is that helper.html can receive messages from framed.html, and can also communicate with home.html.
So essentially, when framed.html loads, it works out its own height, tells helper.html, which passes the message on to home.html, which can then resize the iframe in which framed.html sits.
The simplest way to pass messages from framed.html to helper.html is through a URL argument. To do this, framed.html has an iframe with src='' specified. When its onload fires, it evaluates its own height, and sets the src of the iframe at this point to helper.html?height=N
So HOWTO if bar.net wants to talk to foo.com
- change the url hash on the innermost iframe to the message foo.com/#secret
- have the top level frame read the message on the hash
- poll for hashchange the entrie time
- set up iframes to destroy themselves after each message and just wait for the load event
- resize the iframe on change, them attach an event handler on the resize event that checks for new data
- place another iframe page at other domain that belongs to your server which saving height to cookies. Then with an interval read cookies when it is updated, update the height of the iframe.
source