247

I would like to know if there is an alternative to iFrames with HTML5. I mean by that, be able to inject cross-domains HTML inside of a webpage without using an iFrame.

SaschaM78
  • 4,376
  • 4
  • 33
  • 42
stemlaur
  • 2,471
  • 2
  • 14
  • 3

12 Answers12

122

Basically there are 4 ways to embed HTML into a web page:

  • <iframe> An iframe's content lives entirely in a separate context than your page. While that's mostly a great feature and it's the most compatible among browser versions, it creates additional challenges (shrink wrapping the size of the frame to its content is tough, insanely frustrating to script into/out of, nearly impossible to style).
  • AJAX. As the solutions shown here prove, you can use the XMLHttpRequest object to retrieve data and inject it to your page. It is not ideal because it depends on scripting techniques, thus making the execution slower and more complex, among other drawbacks.
  • Hacks. Few mentioned in this question and not very reliable.
  • HTML5 Web Components. HTML Imports, part of the Web Components, allows to bundle HTML documents in other HTML documents. That includes HTML, CSS, JavaScript or anything else an .html file can contain. This makes it a great solution with many interesting use cases: split an app into bundled components that you can distribute as building blocks, better manage dependencies to avoid redundancy, code organization, etc. Here is a trivial example:

<!-- Resources on other origins must be CORS-enabled. -->

<link rel="import" href="http://example.com/elements.html">

Native compatibility is still an issue, but you can use a polyfill to make it work in evergreen browsers Today.

You can learn more here and here.

Abrar Jahin
  • 13,970
  • 24
  • 112
  • 161
Oriol
  • 11,660
  • 5
  • 35
  • 37
  • 4
    HTML5 web components is interesting. – Krishna Srihari Sep 27 '16 at 06:40
  • 1
    I know this post is a bit old but just want to comment: In reference to AJAX, "It's not idea because it relies on scripting techniques"... So, what's wrong with using scripting? AJAX is the uncontested front-runner of these choices and it's quickly becoming the standard. – nmg49 Oct 13 '17 at 20:12
  • 28
    Unfortunately HTML Imports is an obsolete feature now. https://developer.mozilla.org/en-US/docs/Web/Web_Components/HTML_Imports – Gman Jun 03 '19 at 20:01
  • Any new way to achieve this? –  May 25 '20 at 03:04
  • 4
    Another crucial drawback with iFrames is the fact that there are many websites out there which have set 'X-Frame-Options' to 'sameorigin' and then simply refuse the connection. In this case, your iFrame remains empty. No way to fix that. – Igor P. Jun 10 '20 at 20:35
73

You can use object and embed, like so:

<object data="http://www.web-source.net" width="600" height="400">
    <embed src="http://www.web-source.net" width="600" height="400"> </embed>
    Error: Embedded data could not be displayed.
</object>

Which isn't new, but still works. I'm not sure if it has the same functionality though.

nate
  • 773
  • 5
  • 11
60

object is an easy alternative in HTML5:

<object data="https://github.com/AbrarJahin/Asp.NetCore_3.1-PostGRE_Role-Claim_Management/"
width="400"
height="300"
type="text/html">
    Alternative Content
</object>

You can also try embed:

<embed src="https://github.com/AbrarJahin/Asp.NetCore_3.1-PostGRE_Role-Claim_Management/"
width=200
height=200
onerror="alert('URL invalid !!');" />

Re-

As currently, StackOverflow has turned off support for showing external URL contents, run code snippet is not showing anything. But for your site, it will work perfectly.

Abrar Jahin
  • 13,970
  • 24
  • 112
  • 161
56

No, there isn't an equivalent. The <iframe> element is still valid in HTML5. Depending on what exact interaction you need there might be different APIs. For example there's the postMessage method which allows you to achieve cross domain javascript interaction. But if you want to display cross domain HTML contents (styled with CSS and made interactive with javascript) iframe stays as a good way to do.

Sean
  • 2,632
  • 2
  • 27
  • 35
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • 3
    I need to load content from google. but google cant be iframed, what is the alternative. – Mike Apr 08 '13 at 09:53
  • 18
    @Mike, the alternative would be to use the API for the service you would like to use. Google provides RESTful APIs for most of its services. – Darin Dimitrov Apr 08 '13 at 10:54
21

If you want to do this and control the server from which the base page or content is being served, you can use Cross Origin Resource Sharing (http://www.w3.org/TR/access-control/) to allow client-side JavaScript to load data into a <div> via XMLHttpRequest():

// I safely ignore IE 6 and 5 (!) users
// because I do not wish to proliferate
// broken software that will hurt other
// users of the internet, which is what
// you're doing when you write anything
// for old version of IE (5/6)
xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
  if(xhr.readyState == 4 && xhr.status == 200) {
    document.getElementById('displayDiv').innerHTML = xhr.responseText;
  }
};
xhr.open('GET', 'http://api.google.com/thing?request=data', true);
xhr.send();

Now for the lynchpin of this whole operation, you need to write code for your server that will give clients the Access-Control-Allow-Origin header, specifying which domains you want the client-side code to be able to access via XMLHttpRequest(). The following is an example of PHP code you can include at the top of your page in order to send these headers to clients:

<?php
  header('Access-Control-Allow-Origin: http://api.google.com');
  header('Access-Control-Allow-Origin: http://some.example.com');
?>
Vincent Cantin
  • 16,192
  • 2
  • 35
  • 57
L0j1k
  • 12,255
  • 7
  • 53
  • 65
17

This also does seem to work, although W3C specifies it is not intended "for an external (typically non-HTML) application or interactive content"

<embed src="http://www.somesite.com" width=200 height=200 />

More info: http://www.w3.org/wiki/HTML/Elements/embed http://www.w3schools.com/tags/tag_embed.asp

Thomas Simoens
  • 406
  • 4
  • 11
12

An iframe is still the best way to download cross-domain visual content. With AJAX you can certainly download the HTML from a web page and stick it in a div (as others have mentioned) however the bigger problem is security. With iframes you'll be able to load the cross domain content but won't be able to manipulate it since the content doesn't actually belong to you. On the other hand with AJAX you can certainly manipulate any content you are able to download but the other domain's server needs to be setup in such a way that will allow you to download it to begin with. A lot of times you won't have access to the other domain's configuration and even if you do, unless you do that kind of configuration all the time, it can be a headache. In which case the iframe can be the MUCH easier alternative.

As others have mentioned you can also use the embed tag and the object tag but that's not necessarily more advanced or newer than the iframe.

HTML5 has gone more in the direction of adopting web APIs to get information from cross domains. Usually web APIs just return data though and not HTML.

Adam
  • 3,063
  • 5
  • 35
  • 49
5

I created a node module to solve this problem node-iframe-replacement. You provide the source URL of the parent site and CSS selector to inject your content into and it merges the two together.

Changes to the parent site are picked up every 5 minutes.

var iframeReplacement = require('node-iframe-replacement');

// add iframe replacement to express as middleware (adds res.merge method) 
app.use(iframeReplacement);

// create a regular express route 
app.get('/', function(req, res){

    // respond to this request with our fake-news content embedded within the BBC News home page 
    res.merge('fake-news', {
        // external url to fetch 
       sourceUrl: 'http://www.bbc.co.uk/news',
       // css selector to inject our content into 
       sourcePlaceholder: 'div[data-entityid="container-top-stories#1"]',
       // pass a function here to intercept the source html prior to merging 
       transform: null
    });
});

The source contains a working example of injecting content into the BBC News home page.

John Doherty
  • 3,669
  • 36
  • 38
2

You can use an XMLHttpRequest to load a page into a div (or any other element of your page really). An exemple function would be:

function loadPage(){
if (window.XMLHttpRequest){
    // code for IE7+, Firefox, Chrome, Opera, Safari
    xmlhttp=new XMLHttpRequest();
}else{
    // code for IE6, IE5
    xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}

xmlhttp.onreadystatechange=function(){
    if (xmlhttp.readyState==4 && xmlhttp.status==200){
        document.getElementById("ID OF ELEMENT YOU WANT TO LOAD PAGE IN").innerHTML=xmlhttp.responseText;
    }
}

xmlhttp.open("POST","WEBPAGE YOU WANT TO LOAD",true);
xmlhttp.send();
}

If your sever is capable, you could also use PHP to do this, but since you're asking for an HTML5 method, this should be all you need.

CupOfTea696
  • 1,266
  • 3
  • 14
  • 29
0

The key issue to load another site's page in your own site's page is security. There is cross-site security policy defined, you would have no chance to load it directly in your iframe if another site has it set to strict same origin policy. Hence to find an alternative to iframe, they must be able to bypass this security policy restriction, even in the future, if any new component is introduced by WSC, it would have similar security restrictions.

For now, the best way to bypass this is to simulate a normal page access in your logic, this means AJAX + server side access maybe a good option. You can set up some proxy at your server side and fetch the page content and load it into the iframe. This works but not perfect as if there is any link or image in the content and they may not be accessible.

Normally if you try to load a page in your own iframe, you would need to check whether the page can be loaded in iframe or not. This post gives some guidelines on how to do the check.

PixelsTech
  • 3,229
  • 1
  • 33
  • 33
0

Depending on specific needs a <template> HTML tag can stay helpful here in combination with JavaScript. Here is a short sample:

HTML:

<div id="container"></div>

<template id="template">
  <div>your content</div>
</template>

JavaScript:

const container = document.getElementById("container");
const template = document.getElementById("template");

const clone = template.content.cloneNode(true);
container.appendChild(clone);

For your reference, find more details at MDN Mozilla docs

Oleksa O.
  • 827
  • 8
  • 16
  • What is the benefit of this over using Angular/React, etc? – OneCricketeer Apr 18 '23 at 19:22
  • @OneCricketeer it wasn't pointed in original question whether they want to use Angular/React to achieve it. So I took it as RAW js usage, which is okay method if one want to use it once per project, at my point of view. – Oleksa O. Apr 20 '23 at 12:35
  • The question is 11 years old. Maybe OP simply didn't know about those. So, your response is suggesting not to bring in external libraries? – OneCricketeer Apr 20 '23 at 12:45
  • @OneCricketeer not at all. Everyone decides themselves whether to take it or use external libs. Just as a solution among others. – Oleksa O. Apr 21 '23 at 14:36
-5

You should have a look into JSON-P - that was a perfect solution for me when I had that problem:

https://en.wikipedia.org/wiki/JSONP

You basically define a javascript file that loads all your data and another javascript file that processes and displays it. That gets rid of the ugly scrollbar of iframes.

Mathias Bader
  • 3,585
  • 7
  • 39
  • 61