iframe setting content - javascript

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.

Related

How to use `arrive.js` to find an element arrived inside of a `iFrame'

I require to find the DOM element which is adding inside of a iframe, with the iframe added. for determine to find the element added, I am using this plugin
all i doing from chrome ext.
arrive.js
body>iframe1>iframe.ssueContentIframe2>#SmartReportTabContent1>loopElements>link
like this:
document.arrive(".ssueContentIframe", function() {
console.log('.ssueContentIframe arrived', this);//works
this.arrive('#SmartReportTabContent1', function(){
console.log('arrive 2');//not working
});
});
what is wrong here? any one help me please?
To check for an element within an iframe you need to include the arrive.js library and your script that calls the arrive() function within the iframe.
If you just want to detect whether iframe is loaded there's other solutions, but if you want to muck around in the iframe you have to keep in mind cross-domain policies.
Javascript has a Same-Origin policy in which javascript on the outer page cannot access the contentWindow or DOM (or global state) of the iframe page if it does not share the Same-Origin
-- T. Stone
Seems to me arrive.js isn't the problem, it's trying to mess with an iframe.

How to sandbox a div element?

I am trying to build a content editor. This contenteditor will load a HTML document (with JavaScript) into for example a #result element. The problem with this, is that if inside this HTML element there is for example $("input").hide();, then all of my inputs are gone throughout the whole page, so not just inside the loaded HTML (my goal).
What I want to do with the editor is when a client clicks on an element that represents something in the database, the info of this element will popup and the user will be able to edit this. (So, if a user hovers over a form with the class "contact-form" (which is in the database, connected to the loaded page) a new window will popup with information about this specific form element.
Also, I cannot completely disable Javascript, since the loaded HTML might contain Javascript for styling etc.
My goal: Remove Javascript, that can be annoying when a user loads in an HTML file. Like an alert(); Also, remove the ability for the Javascript to edit somehthing outside it's own DOM.
P.S. I am open to better workarounds like using an iframe for this, BUT I want to be able to hover over elements in interact with them.
Edit: It seems that this question might be a bit too broad, looking at the comments. Summary of my question: How can I disable alert() for a specific div and how can I create a sandbox so that code inside a div, can only change elements from inside that div.
What you're looking for is HTML sanitization. This is the process by which you remove any dangerous content from a snippet of HTML on the server, before it's loaded in the browser. There are plenty of sanitization libraries out there that can strip script tags, object tags, etc. Just remember, you can't sanitize using javascript because by the time you've injected your script, another malicious script may have already loaded and run.
The only way to effectively sandbox a javascript environment is with iframes. You'll notice that websites like CodePen, JSBin and JSFiddle use them extensively. There's something called the ShadowDOM, which is the basis of Web Components, but it isn't very well supported yet.
To make it possible to run your own frontend scripts that allow for hovering, you can inject your script after your sanitization process. This way, if it's loaded inside an iframe your script will also be loaded.
Finally, alert() doesn't belong to any elements on the DOM. You can trigger an alert as soon as the page loads, for example. However, if you're trying to prevent alerts from popping up on user interactions, you could try removing all event listeners from a particular element. This won't be necessary if you sanitize the HTML of script tags, however, since the script wouldn't have had a chance to load so there won't be any event listeners.
You can use ShadowDOM to load an html document into a host node. See also WHY SHADOW DOM?

Giving iframe properties from inside

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.

How to add CSS property to elements outside iframe?

I'm sorry if this wasn't the right place to ask. I'm having trouble figuring this one out.
What I'm trying to do is removing the demo bar provided by marketplaces like themeforest or mojothemes within my own demo site.
But since what appears in the marketplace's live demo of a theme is fetched, it appears within an iframe inside of their site.
I've tried asking in their forums but no one has been helpful.
Is there any way to do about this? An example done in a marketplace would be great.
The Answer is No. It is not possible to modify dome elements outside iframe by a script on site in iframe.
Reason: Since The Marketplace website is Accessing your Demo Site within iFrame at thier server.
Like how you embed a YouTube Video on your Page and Specify a Heading above it etc, does youtube or google map ever try to change their container styles? do they ever change the heading you wrote above the embed code?
Thats it
You cannot (due to the Cross Site Scripting - http://en.wikipedia.org/wiki/Cross-site_scripting) as it is a separated document. But what You can do is to use Web Messenging: http://en.wikipedia.org/wiki/Web_Messaging to affect JS/CSS within the iframe (but this will require actions on both sides).
If you can execute Javascript from within an iframe you can change the elements outside of it with the Window parent Property. Example usage:
parent.document.body.style.backgroundColor = "red";
changes the background of the <body> outside of the iframe.

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

Categories