Difference between iframe, embed and object elements - html

HTML5 defines several embedded content elements, which, from a bird's-eye view, seem to be very similar to the point of being largely identical.
What is the actual difference between iframe, embed and object?
If I want to embed an HTML file from a third-party site, which of these elements could I use, and how would they differ?

<iframe>
The iframe element represents a nested browsing context. HTML 5 standard - "The <iframe> element"
Primarily used to include resources from other domains or subdomains but can be used to include content from the same domain as well. The <iframe>'s strength is that the embedded code is 'live' and can communicate with the parent document.
<embed>
Standardised in HTML 5, before that it was a non standard tag, which admittedly was implemented by all major browsers. Behaviour prior to HTML 5 can vary ...
The embed element provides an integration point for an external (typically non-HTML) application or interactive content. (HTML 5 standard - "The <embed> element")
Used to embed content for browser plugins. Exceptions to this is SVG and HTML that are handled differently according to the standard.
The details of what can and can not be done with the embedded content is up to the browser plugin in question. But for SVG you can access the embedded SVG document from the parent with something like:
svg = document.getElementById("parent_id").getSVGDocument();
From inside an embedded SVG or HTML document you can reach the parent with:
parent = window.parent.document;
For embedded HTML there is no way to get at the embedded document from the parent (that I have found).
<object>
The <object> element can represent an external resource, which, depending on the type of the resource, will either be treated as an image, as a nested browsing context, or as an external resource to be processed by a plugin. (HTML 5 standard - "The <object> element")
Conclusion
Unless you are embedding SVG or something static you are probably best of using <iframe>. To include SVG use <embed> (if I remember correctly <object> won't let you script†). Honestly I don't know why you would use <object> unless for older browsers or flash (that I don't work with).
† As pointed out in the comments below; scripts in <object> will run but the parent and child contexts can't communicate directly. With <embed> you can get the context of the child from the parent and vice versa. This means they you can use scripts in the parent to manipulate the child etc. That part is not possible with <object> or <iframe> where you would have to set up some other mechanism instead, such as the JavaScript postMessage API.

One reason to use object over iframe is that object re-sizes the embedded content to fit the object dimensions. most notable on safari in iPhone 4s where screen width is 320px and the html from the embedded URL may set dimensions greater.

Another reason to use object over iframe is that object sub resources (when an <object> performs HTTP requests) are considered as passive/display in terms of Mixed content, which means it's more secure when you must have Mixed content.
Mixed content means that when you have https but your resource is from http.
Reference: https://developer.mozilla.org/en-US/docs/Web/Security/Mixed_content

iframe have "sandbox" attribute that may block pop up etc

Related

Is it possible use web audio API with vimeo iframe

I'm trying to extract or just analyze the audio from a vimeo video with the web audio API and was wondering if it's possible and how.
Right now I get the error:
Uncaught TypeError: Failed to execute 'createMediaElementSource' on 'AudioContext': parameter 1 is not of type 'HTMLMediaElement'
… when I try a createMediaElementSource(video) where video is my iframe
Unfortunately I think it is not possible to do what you want. At least not exactly in the way you want it.
The createMediaElementSource() factory function only works with media elements. And those are only <audio/> and <video/> elements. This is why it doesn't work when you use it with the <iframe/> directly.
Normally you would query such a media element for example by its id like this:
document.querySelector('#myAudioElement');
But this is not that easy if the element is inside an <iframe/>. Then it is only possible to query an element if the <iframe/> and the parent document do have the same origin. This is because of the same-origin policy which is a security feature. Imagine what an attacker could do if it was possible to load any page in an <iframe/> and then modify it at will.
Of course it is a hindrance for your use case. Maybe building a browser extension is an option for you because they have usually more privileges and can query the DOM of any page the browser loads.
Alternatively it is also possible to disable the same-origin policy in some browsers. But that is usually only useful during development because you can only disable this policy for the whole browser which is a security problem unless you only open sites that you fully trust.

Can an iframe use assets from parent page?

I would like to use a font in an iframe which I know will be loaded already in the parent html page: can the iframe css simply refer to it as if the user has it already? or will I have to load it again via #font-face?
A more general approach complementary to #Mr Lister s comment:
An inline frame (<iframe>) loads another HTML document within your HTML document and embeds it. Simplified you could say it is a website within a website.
The embedded CSS does not interfere with its parents CSS or the other way around since they belong to separate documents and only live within them. As #Mr Lister already pointed out, resources that are referenced in both documents will not be loaded twice.
Any changes to the appearance should be made in the child document itself rather than after loading it in an iframe. You could, however, use JavaScript and its libraries to inject basically anything (stylesheets etc.) into the loaded document. For security reasons browsers generally only allow this for iframes that have to the same domain as the parent. Check out this thread to learn more about injecting via JavaScript: Override body style for content in an iframe.
CSS does not cascade into documents loaded into iframes, they are separate documents.
You will need to include #font-face in the stylesheet loaded into that document.
The file shouldn't be downloaded again, but loaded from the browser's local cache (assuming the server hosting the font has a reasonable configuration).

HTML object tag to embed a web page

We have a feature in our application which allows users to select a set of assets (images, videos etc.) and generate an embed code for those, which can be embedded in another web page. As of now we use iframes to implement in the embed code where page pointed by src attribute of iframe spits out HTML to embed.
For some security reasons we want to get rid of iframes and replace that with something else like an object tag, script tag etc.
My question is about object tag. Primary use of object tag seems to be to embed a video, a pdf etc. I know it can be used to embed an entire webpage just like what we want. But my question is - is that recommended? The webpage we want to embed will have a set of assets with options to sort, download, share, preview those assets.
So will it be a good practice to use object tag for embedding such a complex web page? Or is it meant for minimal usage like embedding a video clip, a slideshow etc.?
Depending on the type of technology you are using, you can do something similar.
With your request you are getting into the portlet/web part discussion, where you want to embed portlets (mini apps). There is no object tag you can use (to my knowledge its only image, applet and iframe I think) from the client side, but you might be able to pre-load the parts before you send the user the final page (say, like wordpress widgets in php).
Otherwise you need to go the Javascript route, and do some kind of lazy loading of your 'widget/applications' as needed.

How to detect whether an HTML page contains a video?

I would like to know whether it a possible to detect whether a HTML page contains a video.
I know that one possible way is to look for ".swf" in the HTML source code. But most of the pages do not contain the file name.
For example, given following URL and possibly its source code, is it possible to find out whether it contains a video:
http://www.cnn.com/video/
There are many ways to embed Video into a HTML page - as Flash Video or instances of Platform-Specific players through <object> and <embed> tags (but not every one of those tags is a video! The same holds true for .swf - it's just the file extension of Flash files, Video or not), the new HTML 5 <video> tag... They are not impossible to find out but it's a lot of work to catch all possible player types, formats and embed codes, and will result in a lot of false positives / negatives.
Then, there are JavaScript libraries that initialize players after the containing page has loaded - those are almost impossible to detect.
It's still a very complex issue to get video into a web page reliably, and subsequently, it's even more complex to find it out. Depending on what you are trying to achieve, I would consider dropping it.
For your case (CNN site) you can parse Open Graph micro-markup for a video information.
Meta tags such as og:video:type, og:image will help you.
Video hosting services usually support micro-markup, e.g. open graph or scheme.org.
So you can parse these markups.
Check if an <object> tag exists in the DOM and check its content type and parameters. You will find the pattern by yourself.
You can also search for .flv, or .mp4 in the source code.

Work around for the same origin policy problem

I have a problem where I have a frameset consisting of a parent frame loaded from one domain and a contained frame from a different domain. The contained domain also sets a cookie before the frameset is loaded. However, because of the 'same orgin' policy, enforced by most browsers, a contained frame will not pass cookies if it is not from the same domain as the parent.
Unfortunately I have no control over the parent frame (or its url) and the url for the contained frame is effectively static. So the only way to pass information to the contained site is via cookies.
The only solution I have come up with is to reload the contained domain in the parent frame but this negates some of the value of using frames in the first place.
Does anyone have a better work around for this problem?
There are a couple of methods of getting around the Same Origin Policy that is preventing your iframes from speaking to each other. If you control both servers then you can use Flash's crossdomain.xml file. If you don't control one of the servers or you would like to use JavaScript, then you are forced to use a "Cross-Domain Proxy", such as this one for java or python or php.
Cross-Site XHR is another option but it isn't supported by all browsers.
There are a lot of ways to do this. Here are two that I've used:
Have both the parent and child load
a script from a common source, using
a tag. Scripts loaded in
this way don't have same-origin
issues, and the data they return
becomes part of the document object
and can interact with other scripts
loaded by the document (this is the
way that AJAST works).
Create a reverse proxy in the parent domain, and load the frame via this proxy. To the browser, it appears that they're both served from the same domain. The downside is that this can affect caching, and bypasses any content delivery network (eg, Akamai) that you might be using.
There is also a right way of doing this in HTML 5 with postMessage.
See here: http://ajaxian.com/archives/cross-window-messaging-with-html-5-postmessage
One more thought in to this, where u can use Cross Domain Messaging API to send messages from one frame to another. here is an example! Read more on this.