How to resize iframe from another domain
-Edit
Scroll down for some solutions .. or read how NOT to do it: D
After many hours of hacking code, the conclusion is that everything inside the iframe is inaccessible, even the scroll bars that appear in my domain. I tried many methods to no avail.
To save your time, don’t even go down this route, just use sendMessages for cross-domain communication. There are plugins for HTML <5 that I use- Go to the bottom for a nice example :)
For the past few days, I have been trying to integrate iframes into the site. This is a short-term solution, while the other side is developing, and the API (may take months ...) And since it is like a short-term solution that we wanted to use easyXDM-, I have access to another domain, but it is quite difficult to ask them add p3p header as it is .....
3 frames
The closest solution I found was 3 iframes-, but it has smart chrome and safari, so I cannot use this.
open in chrome
http://css-tricks.com/examples/iFrameResize/crossdomain.php#frameId=frame-one&height=1179
Scroll bar measurement
I found another post on how to use scrollheight to try to resize the form. Theoretically, this works well, but I could not apply it correctly using the iframes scroll height.
document.body.scrollHeight
That obvoisly uses body height (cannot access these properties, 100% based on the canvaz client display, not the height of the x-domains document)
I tried using jquery to get iframes height
$('#frameId').Height() $('#frameId').clientHeight $('#frameId').scrollHeight
return values differ in chrome, etc. - or just don't make sense at all. The problem is that everything inside the denied frame is even a scrollbar ...
Computational Styles
But if I check the element in the chrome iframe, it bladdy shows me the sizes of the documents inside the iframe (using jquery x-domain to get iframe.heigh - access is denied). In computed CSS
there is nothing,
Now, how did chrome figure it out? (the edit- browser re-renders the page using its assembly in the rendering engine to calculate all of these parameters - but they are not tied anywhere to prevent cross-domain fraud .. so ..)
HTML4
I read the HTML4.x specification and it says that there should be read-only values through the document.element document, but access to them is denied through jquery
Proxy framework
I went along the path of proxying the site and calculated that everything is in order .. until the user logs in through the iframe and the proxy server receives a login page instead of the actual content. Also for some calls the page is twice unacceptable
http://www.codeproject.com/KB/aspnet/asproxy.aspx
http://www.johnchapman.name/aspnet-proxy-page-cross-domain-requests-from-ajax-and-javascript/
Redisplay page
I haven’t gone that far, but there are jscript engines that will look at the source and re-render the page based on the source file. but it will require hacking these jscripts .. and this is not an ideal situation for commercials ... and some invoke pure java applets or server visualization
http://en.wikipedia.org/wiki/Server-side_JavaScript
http://htmlunit.sourceforge.net/ <-java not jscript
http://maxq.tigris.org/
EDIT 09-2013 UPDATE
All of this can be done using HTML5 sockets. But easyXDM is great for non-HTML5 complaint pages.
Solution 1 A very big solution!
Using easyXDM
On your server, you created a page in the form
<html> <head> <script src="scripts/easyXDM.js" type="text/javascript"></script> <script type="text/javascript" language="javascript"> var transport = new easyXDM.Socket({ remote: "http://www.OTHERDOMAIN.com/resize_intermediate.html?url=testpages/resized_iframe_1.html", </script> </head> <body> <div id="embedded"></div> </body>
and in the caller domain they just need to add intermiedate_frame html and easyXDM.js in the same place. As a parent folder - then you can access relative directories or a folder that is at your disposal just for you.
OPTION 1
If you do not want to add scripts to all pages, look at option 2!
Then they can simply add plain jscript to the end of every page that needs to be resized. You do not need to enable easyxdm on each of these pages.
<script type="text/javascript"> window.onload = function(){ parent.socket.postMessage( (parseInt(document.body.clientHeight)) + "," + ( document.body.clientWidth ) ); }; </script>
I changed the parameters that it sends. If you want the width to work correctly, then pages on another domain should include the page width in a style that looks something like this:
<style type="text/css"> html, body { overflow: hidden; margin: 0px; padding: 0px; background-color: rgb(75,0,85); color:white; width:660px } a { color:white; visited:white; } </style>
This works great for me. If the width is not included, then the frame behaves a little strange, and it tries to guess what it should be .. and will not be reduced if you need it.
OPTION 2
Change the intermediate frame to poll changes
Your intermediate frame should look something like this.
<!doctype html> <html> <head> <title>Frame</title> <script type="text/javascript" src="easyXDM.js"> </script> <script type="text/javascript"> var iframe; var socket = new easyXDM.Socket({ </script> <style type="text/css"> html, body { overflow: hidden; margin: 0px; padding: 0px; width: 100%; height: 100%; } iframe { width: 100%; height: 100%; border: 0px; } </style> </head> <body> </body> </html>
The interval may be more efficient for chaeck if the size has changed and is only sent if the resizing is sending messages every 500 ms. If you complete this check, you can change the poll to 50 ms! have some fun
Work in browsers and fast. Great debugging features!
Excellent Work to Sean Kinsey who made the script!!!
Solution 2 (works, but not very good)
Therefore, if you have mutual agreement with another domain, you can add a library to handle sendmessage. If you do not have access to another domain, keep looking for more hacks- because I could not find or fully justify them that I found.
Thus, Head tags will be included in another domain.
<script src="scripts/jquery-1.5.2.min.js" type="text/javascript"></script> <script src="scripts/jquery.postmessage.min.js" type="text/javascript"></script> <script src="scripts/club.js" type="text/javascript"></script>
In club.js there are only some user calls that I made to resize calls and contains ..
$(document).ready(function () { var parent_url = decodeURIComponent( document.location.hash.replace( /^#/, '' ) ),link;
And your page will do all the hard work and has a good script ...
//This is almost like request.querystring used to get the iframe data function querySt(param, e) { gy = e.split("&"); for (i = 0; i < gy.length; i++) { ft = gy[i].split("="); if (ft[0] == param) { return ft[1]; } } } $(function () { // Keep track of the iframe dimensions. var if_height; var if_width; // Pass the parent page URL into the Iframe in a meaningful way (this URL could be // passed via query string or hard coded into the child page, it depends on your needs). src = 'http://www.OTHERDOAMIN.co.uk/OTHERSTARTPAGE.htm' + '#' + encodeURIComponent(document.location.href), // Append the Iframe into the DOM. iframe = $('<iframe " src="' + src + '" width="100%" height="100%" scrolling="no" frameborder="0"><\/iframe>').appendTo('#iframe'); // Setup a callback to handle the dispatched MessageEvent event. In cases where // window.postMessage is supported, the passed event will have .data, .origin and // .source properties. Otherwise, this will only have the .data property. $.receiveMessage(function (e) { // Get the height from the passsed data. //var h = Number(e.data.replace(/.*if_height=(\d+)(?:&|$)/, '$1')); var h = querySt("if_height", e.data); var w = querySt("if_width", e.data); if (!isNaN(h) && h > 0 && h !== if_height) { // Height has changed, update the iframe. iframe.height(if_height = h); } if (!isNaN(w) && w > 0 && w !== if_width) { // Height has changed, update the iframe. iframe.width(if_width = w); } //For debugging only really- can remove the next line if you want $('body').prepend("Recieved" + h + "hX" + w + "w .. "); // An optional origin URL (Ignored where window.postMessage is unsupported). //Here you must put the other domain.com name only! This is like an authentication to prevent spoofing and xss attacks! }, 'http://www.OTHERDOMAIN.co.uk'); });
OPTION 3
They are currently a small JS library for managing cross-domain resizing of iFrames, but the iFrame still needs a bit of JavaScript, but it's just 2.8k (765 Gzipped bytes) of embedded JS that has no dependencies and it does nothing until called by the parent page. This means that this is a good guest in other people.
This code uses mutationObserver to detect DOM changes, and also looks for resize events so that the iFrame remains the size of the content. Works in IE8 +.
https://github.com/davidjbradshaw/iframe-resizer