I'm developing an application that is feed a URL containing a session token from an API. This URL will grant the user of the application the ability to view search results from 3rd party databases via the API.
The issue that I'm facing is that when presenting the results (The URL) in an iframe it looks very ugly due to the iframe's scroll bar. I've poked about got the usual Google results, but I'm finding I'm quite stumped as to how to expand the iframe's height to match the incoming content.
I found an example of exactly what I'd like to happen but on trying to replicate the code I'm having no luck.
The link in question ... As you can see the page loads an iframe into a basic HTML table and expands to accommodate the size of the content in the iframe.
Here's the source code for the HTML:
<html>
<body>
<table width="100%" border=1>
<tr><td>Header</td></tr>
<tr><td>Navigation</td></tr>
<tr><td>
<iframe onload="resize(this)" src="/test/phpinfo.php">
</iframe>
</td></tr>
<tr><td>footer</td></tr>
</table>
<script>
function resize(elem){
var outer=elem;
var inner=elem.contentDocument.documentElement;
outer.style.border="0";
outer.style.overflow="hidden";
outer.style.height=Number(inner.scrollHeight+10)+"px";
outer.style.width=Number(inner.scrollWidth+10)+"px";
}
</script>
</body>
</html>
Nothing special right? But copypasta of the code (obviously changing the src) does nothing. I feel like I'm taking crazy pills here, this should be 2 second job, but it's not working for me. This is all client side stuff, right? No voodoo magic happening on the server.
So ladies and gentlemen, what am I doing wrong, or how can I better do this? Please bear in mind that I have no ability to effect the HTML in the iframe as it is served up via an API and I can't touch it.
Thank you
EDIT : This is the reason it won't work Same Origin Policy.
you can only access the iframe contentDocument with javascript when iframe origin and the iframe src origin equal and matches each other.
otherwise the browser dont allow you to access the inner contentDocument
Blocked a frame with origin "http://example.de" from accessing
a frame with origin "http://otherorigin.example.de". Protocols,
domains, and ports must match.
your posted example page origin
http://frank.bridgewater.edu/test/iframeResize/
and iframe src origin
http://frank.bridgewater.edu/test/phpinfo.php
matches (equal origins). so here it is working and the script can access the iframe contentDocument
Related
I am experimenting with making a website where I have two iframes with other webpages side by side, and would only like to show a certain part of these websites.
Trying to edit the innerHTML of these websites throws errors regarding cross-page security problems.
How can I run Javascript inside these iFrames in a safe manner? If this is not possible, is there a good atlernative for iFrames where I can have to websites side-by-side?
It's not important for me to be able to edit both iFrames, only one of them need to be editable.
An iframe is just a 'hole' in your page that displays another web page inside of it. The contents of the iframe are not in any shape or form part of your parent page.
If your iframe is loaded from the same domain as your parent, then you can access the DOM of the document in the iframe from the parent.
Considering the iframe is from the same domain, Try using the below code and see if it works. The below code will add CSS changes to the iframe. If this works for you, then you can run javascript as well.
<script>
var iframe = document.getElementById("frame1");
$('iframe').load( function() {
$('iframe').contents().find("head")
.append($("<style type='text/css'> .lt{display:none;} </style>"));
});
</script>
If you are getting "permission denied type errors.", I think what you are doing is subject to the same-origin policy. This should be the reason why you are getting permission denied type errors.
Here you can check the possible solutions.
Unable to access iframe content (same-origin policy)
I'm trying to automate interactions with a website that I don't control. Notably for this discussion, the page from the site contains several iframes. For example, consider the source of the imaginary (but comparable) page https://www.chicken.com/a/b/hamburger.aspx to look something like:
<html>
...
<iframe id="iframe_a" src="meatloaf.aspx"></iframe>
<iframe id="iframe_b" src="stuffing.aspx"></iframe>
...
</html>
Notably, the 'src' attributes of the iframes are relative, so they are to be loaded from the original domain (www.chicken.com/a/b/ in this case) and there doesn't seem to be any 'Same Origin' issues, since I can login to the site and interact with it just fine. However, this all changes when I try to interact with the iframes using the Chrome dev console. For instance, this is what happens when I try to get the contents of one of the iframes using jQuery:
$('#iframe_a').contents()
jquery-1.11.3.min.js:2 Uncaught DOMException: Failed to read the 'contentDocument' property from 'HTMLIFrameElement': Blocked a frame with origin "https://www.chicken.com" from accessing a cross-origin frame.(…)
My (wrong) intuition is that since the sources of these iframes is the same domain as is the original page, that javascript interactions in the console should be under the auspices of that original domain, and everything should be fine. But clearly I'm not understanding the nuances of Same Origin. Can someone enlighten me about how it works in this case? And perhaps suggest a way to manipulate the contents of this iframe from a running browser?
You might know HN, but you maybe also do not like the fact of clicking around in many tabs/going back and forward. I thought about making some page on which both webpage and links from HN are. So I made this: http://goodfrontpage.com/direct
But there are 2 Problems:
First: How to determine if a page doesn't allow in it's http-headers to open it in something like this:
<iframe class="webpage" src="{{post.url}}" ></iframe>
or this:
<object class="webpage" data="http://asfasfasfa.com" >
<embed class="webpage" src="http://asfasffvasf.com" > </embed>
Error: Webpage not accessible!
</object>
This is true for pages like github.com, eff.org or youtube.com
Second: Is there any possibility to fetch the sites in a different way allowing me to display all pages?
If you want to embed a webpage within another one then you should use the iframe element:
<iframe src="http://asfasffvasf.com"/>
You can style this like any other block element, and set an explicit width and height.
Some pages ask browsers not to include them within iframes (using the X-Frame-Options header). I don't think there's an easy way to solve this on the client side, but you could create a simple backend or proxy to request the page you want and return the content. This gets round the iframe restriction because you're now including content from your own domain.
This does have a couple of security issues to be aware of:
You've now made a backend which can be used to download any page on the Internet. There's a denial of service vulnerability if someone makes lots of requests to download huge pages.
The pages you're including will no longer be restricted by the same origin policy. Scripts on those pages will be able to interact with everything on the parent page. This may be a problem if you plan on creating login functionality in the future.
Seems like you are looking for iframe property.It specifies an inline frame.
An inline frame is used to embed another document within the current HTML document.
<iframe src="http://asfasfasfa.com"></iframe>
I have the following HTML markup (don't ask....)
- document //main site
- <iframe> //my site
- <iframe> //site within my site
- <frame>
- <a onclick="JavaScript:parent.parent.location.href='http://bla.com;return false;'">
Basically, main site is calling my site in an iframe. I, in turn, also have an iframe on my site where I'm calling 3rd site. The third site has a frameset with a frame in it that has a link. When clicking on this link, it has to change the url of my site. My site and my child site are on the same domain. When I'm running my site as "stand-alone" (not in iframe) the above code works fine in all browsers.
Once I open my site in an iframe of the main site, it looks like the above code is trying to change the source of the main site. In FireFox I get a console message "Access to property denied". In IE it opens up a new window with my site not in the main site anymore.
What is the correct JavaScript to change the #src attribute on my site when I'm within an iframe?
You are banging your head against the wall that is the same origin policy here. This is XSS country and strictly forbidden, no way around it, unless both domains agree to talk together.
You can read more about cross domain communication using iframes, but again, unless the different domain agree to talk together, you are out of luck.
Although this might seem frustrating, be glad of this rule next time you use homebanking ;)
Can you try something like this
<document> //main site
<iframe id="my_iframe"> //your site
<iframe> //site within your site
<frame>
<a onclick="JavaScript:Top.document.getElementById('my_iframe').location.href='http://bla.com;return false;'">
Top refers to the main window, and then getElementById('my_iframe') will give you your iframe element.
I believe that you're trying to do communication between different pages.
You may take a look this API: HTML5 Cross Document Messaging
Basically, if you want to tell the parent iframe to navigate to a certain url, you can do this:
In the site within my site html:
// onclick of your anchor, post message (an event) with an expected origin
window.postMessage("http://bla.com", "www.sitewithinmysite.com");
In my site html:
// listen to the event "message"
window.addEventListener("message", messageHandler, true);
function messageHandler(e) {
// only recognize message from this origin
if (e.origin === "www.sitewithinmysite.com") {
// then you can navigate your page with the link passed in
window.location = e.data;
}
}
You might want to have the pages communicate using AJAX. Have the site that needs to change its URL listen by long polling to to a node.js server.
I'm trying to get an IFrame inner HTML using below code.
<iframe src="http://www.msn.com"
width="100%" height="100%" marginwidth="0"
scrolling="no" frameborder="0" id="divInfo"
onreadystatechange="MyFunction(this);"></iframe>
JavaScript code is
function MyFunction(frameObj)
{
if (frameObj.readyState == "complete")
{
alert(frameObj.document.body.innerHTML);
}
}
But the alert shows me the html of current document. How can i get the inner HTML of iframe when the frmae ready state is complete.
If i use alert(frameObj.contentWindow.document.body.innerHTML); it gives me Access is denied error.
Thanks in advance.
Access is denied error is caused by the same origin policy.
Since your page is hosted on http://www.example.com/ (For example), if you try to access details on http://www.msn.com/, the browser won't let you since they are from 2 different domains.
However, if you are trying to access data from the same domain - Hosting page: http://www.example.com/index.html, IFrame's page: http://www.example.com/iframe.html, then you should be able to get the content.
For more information on the Same Origin Policy, here's a link: http://en.wikipedia.org/wiki/Same_origin_policy
BTW, you may want to use frameObject.contentDocument instead
<script type="text/javascript">
function documentIsReady(frameObject) {
alert(frameObject.contentDocument.body.innerHTML);
}
</script>
... and you can also use the onload instead of onreadystatechange...
<iframe src="iframe.html" onload="documentIsReady(this);"></iframe>
You can't read the contents of an <iframe> that has content from a different domain than that of the parent page.
You can only do that if it adheres to the same origin policy (meaning the iframe is at the same server as the parent document).
Anyway, this was answered here :)
As has been said previously, you cannot get the contents of an <iframe> if its source is not from the same origin.
This also applies to most other ways of getting external content, such as using ajax to load source code from another page. ie: $('#div').load('http://www.google.com');
To load external content, the content must comply with the same origin policy.
This means that the content must be on the same protocol and host.
Wikipedia Article Linked Above:
httpː//www.example.com/dir/page2.html --> Success Same protocol and host
httpː//www.example.com/dir2/other.html --> Success Same protocol and host
httpː//username:password#www.example.com/dir2/other.html --> Success Same protocol and host
httpː//www.example.com:81/dir/other.html --> Failure Same protocol and host but different port
https://www.example.com/dir/other.html --> Failure Different protocol
http://en.example.com/dir/other.html --> Failure Different host
http://example.com/dir/other.html --> Failure Different host (exact match required)
http://v2.www.example.com/dir/other.html --> Failure Different host (exact match required)
Simply put, it must be on the same website. So while example.com/hello.html can load content from example.com/goodbye.html, it could not load content from google.com/content.html
Also, it must be on the same domain. Sub domains are considered to VOID the same domain policy so while weebly.com/hello.html can load content from weebly.com/goodbye.html, it could not load content from user1.weebly.com/content.html
There are of course workarounds, as usual, but that's another story all together. Actually, this is quite relevant to the question. So here is a wonderful questions 'thread' on all the ways to bypass it.