Giving iframe properties from inside - javascript

So I am currently working on an application that runs on top of the customers page inside its own iframe.
Application works in backbone and everything else except the initialization of the iframe is done inside the iframe. Initialization happens with a small javascript snippet that the client will copy to their footer.
The problem I'm currently having is that I have to inject a CSS file to the parent site in order to style my iframe correctly when it's rendered and I really don't think that I should tamper with clients page at all since CSS might have some conflicts in it.
Is there any better way to style the iframe than the current way of doing it?

I think you have two different options;
Inline iframe styles
Give your client a pre-styled iframe to embed, like this
<iframe src="yoururl.com/client"
frameborder="0"
style="border: 0; width: 100%; height: 600px;">
</iframe>
Embed through script tag
Create a small script tag (that you host) that you give to your client. Inside the script you dynamically create the iframe dom element and possibly other external css-files that you need
Host a JS file, like //yoururl.com/iframe.js
var iframe = document.createElement("iframe");
iframe.setAttribute("src","http://yoururl.com/client");
document.write("<div id='mycontainer'></div>");
document.getElementById("mycontainer").appendChild(iframe);
Then you can give this to your client to put in their page where they want the iframe to show up.
<script src="//yoururl.com/iframe.js" type="text/javascript"></script>

You can provide your css separately to the client. If that is not an option, then you need to do it the way you are doing now (injecting the parent style from within the iframe). However, this does not seem to be a good idea, unless your css rules are pretty unique.

There are many ways but it could be possible that no one is applicable:
Ask the client to style your iframe (inline or with css)
publish the iframed content on the same domain of the main website and check if the parent frame is accessible via javascript
Ask the Client to enable the header "X-Frame-Options". Maybe with something like "ALLOW-FROM SAMEDOMAIN, www.youriframedomain.com". It seems it is deprecated, check for Content-Security-Policy instead.
embed it via script tag
Check for window.postMessage: it requires anyway an additional script in the main website that listens for the message (it could be the css text itself) from the iframe and applies the new style

You should be able to use window.frameElement to refer to the iframe element which your page is embedded in. With that reference, you should be able to modify the style attribute to change how the frame renders.

Related

How to load HTML file with style without affecting the rest of the page styles?

I am creating a basic email client for myself in electron. When I load an email, that email data needs to be displayed inside a div element that looks like this <div id="emailDisplay"></div>. The only problem is that this html can contain embedded stylesheets which then affect the rest of the page. I tried using an iframe but when one of the elements failed to load (such as an image), it caused an exception and my other needed JavaScript is never executed. The exact error is net::ERR_CONNECTION_TIMED_OUT. So what I'm asking is how can I display this HTML without it affecting the rest of the document's styles or how can I catch and ignore the iframe error? Thanks in advance.
Only ancient email clients support running JavaScript, to do so opens so many security vulnerabilities, not advised. Iframe creates another browser context. Each browser context is a complete document environment, is not possible for the iframe CSS to affect the parent CSS.
Well, what about using a tag within your HTML?
It would still being HTML and if you specify it to style just one tag it will work.
<div id="emailDisplay"></div>
<style>
#emailDisplay {
background-color: red;
}
</style>
Another way of resolving this problem is by creating encapsulated javascript components (maybe with Vue or React)

iframe setting content

I have been searching for this for days and was wondering if anyone could help me with the answer to this.
So, I am currently building a system which allows users to create html pages which can include css and js links and possibly inline scripts/styles within it.
I want the user to preview their output, i was originally using a div tag and adding the html output to it but as all the extra styles and scripts also affected the parent page, i decided the only option was probably to use an iframe to put the content in.
To stop bootstrap links and Jquery conflicts to the parent element, i need to run the iframe in a sandbox environment from what i know but i have no idea how to set the content of the iframe when its in sandbox mode.
If you try:-
$("example iframe element").contents().find("body").html("example html inline styles etc");
this does not work and blocks access due to the iframe being sandboxed and not allowing the origin.
Sandboxing an iframe seems to be the only way to stop multiple instances of Jquery "one on the parent and one in the iframe" from conflicting, i did try noConflict which seems to work but that does not fix conflicting multiple bootstraps being loaded in the parent and iframe elements.
does anyone know either how to add content at runtime to a iframe that is sandboxed without getting blocked access or a different unique container approach i can use?
i appreciate any help or guidance anyone could give on this as i cannot really find much information about it.
I have finally found out what the problem is with this situation, i do not need a sandboxed iframe as i now know why Jquery and Bootstrap are conflicting without having to sandbox the iframe. I see lots of posts telling you to use something like the code below to put content in an iframe.
$("example iframe element").contents().find("body").html("example html inline styles etc");
the problem with the method above is that its opening the iframe up for putting content inside it but its not specifying the closing of the iframe.
This is why even on a normal none sandboxed iframe Jquery and Bootstrap conflict because its leaking back into your parent page by not being closed. The real method for putting content into an iframe directly should be the code below as it ensures the connection is closed off appropriately.
var myIframe = document.getElementById("ID OF THE IFRAME")
var iframeDoc = myIframe.contentWindow.document;
iframeDoc.open();
iframeDoc.write("HTML HERE");
iframeDoc.close();
by doing the above code you are not only modifying the content inside the iframe but your also closing it off once you have finished writing the content. This is very important in ensuring Iframes stick to their purpose as being a completely isolated page element and it stops js and css leaks into your parent page.
i hope this answer helps save time for anyone else who comes across this particular problem with iframes and is adding content at run time using the wrong method.

Iframe inside Iframe cant do changes

I have one iframe inside on iframe and with this code i want to change the src of an image
window.top.frames[0].frames[0].document.getElementById("maquina").src = "https://developer.cdn.mozilla.net/media/img/mdn-logo-sm.png";
and when i try it it work but i cant see changes in the page, only in code when e read .src
of that element
You cannot manipulate the contents of an iframe from within the parent frame without a global method for accessing the child DOM. There is an answer Here that suits your needs, but I will copy below for reference:
In the child iframe:
parent.childGetElementById = function (id) {return document.getElementById(id);}
parent.childLoaded();
In the parent:
function childLoaded() {var dom = childGetElementById('someid');}
Assuming you actually have access to the child page, I would recommend modifying your design away from the use of iframes.
[Answering the comment]
Well it depends on if you're just using straight HTML, or a scripting language (like PHP). If pure HTML, you can use a server side includes with
<!-- #include virtual="path/to/included/file.html" -->
In PHP, you can include the page like this
require('/real/path/to/included/file.php');
Don't get me wrong, iFrames can be useful in some specific situations (circumventing cross-domain origin policies, oAuth implementations, etc); they are more often abused than correctly used.

Creating a Simple Layout/Style Editor

I am trying to create a layout/style editor similar to what is available on blogger. I noticed that they use an iframe, but the iframe has to refresh everytime you make a change. I am looking to do something more responsive. For example, if i change the width of a div I would like to see this change happening while I move the slider.
I was wondering if something like this is possible with the iframe setup using jquery/etc to modify the source of what is in the iframe, or is it better to not use an iframe?
The iframe would be used to load an existing webpage that is online.
The good thing with an iframe is that is not interfeering the rest of the page (you can use diffrent CSS, scripts, variable names and so on). TinyMCE and other editors uses iframe for its content. And yes its possible to access the iframe directly from jQuery:
See this link, http://jsbin.com/ajatix/edit#javascript,html,live

getting dynamically content height of iframe by javascript

first i did my research on this topic after reading and applying so many JS i posting this problem,
i am trying to apply iframe in which i get content from some other domain.
i m trying to set the iframe height on the base of scrollheight of the content inside the iframe but failed to do so
i tried to use onload event of iframe but failed...
please help me i need to set the height of iframe dynamically by any mean necessary ..
if the code would be provided in Javascript that would be helpful to me
Thanks in advance
For security reasons, it is not possible to interact with a frame in a different domain.
That includes measuring its content.
#SLaks is correct. If the iframe content is on a different domain you cannot access its contents directly.
What you could do (and what I recently just did) is setup a proxy that pulls the content in via cURL (in php but im sure whatever server side language has something that is the equivalent). The iframe content is then on the same page and you can access the height of it via:
var _iframeHeight = $('#iframe').contents().find('body').height();
$('#iframe').height(_iframeHeight);
Also I forgot to mention (#SLaks thanks for the reminder) You would have to check all the script/style/image tags and check/add an absolute url to it. The proxy can get pretty tricky but it will get it done.
If you are able to alter the content inside the iframe, for example if you are the author or can contact the author of that iframe content, you can setup a double-iframe trick to send the height of the iframe to your main page.
Here is how that can be accomplished:
In your main page (AAA.com/mainpage.htm) you put an iframe (BBB.com/mainframe.htm).
Together with your main page, you create another page (AAA.com/heightproxy.htm)
You make that BBB.com/mainframe.htm would create an invisible iframe with AAA.com/heightproxy.htm inside.
Result: BBB.com/mainframe.htm on it's onload event can load it's iframe AAA.com/heightproxy.htm with some parameters added to URL. For example, it can put it's new height/width there into the parameters. Also, AAA.com/heightproxy.htm can access all JS function in AAA.com/mainpage.htm - as they are in same browser window and share same domain. This way it can redirect the width and height it received to the mainpage.
Disclaimer: This trick is only possible if you can modify the source of the iframe you need to include.
You cannot interact main page from iFrame if content is loaded from different URL (you can measure height from iframe, but cannot pass it to main page).
That can be overridden by loading content via simple proxy script.

Categories