HTML5的替代方案:与iFrames不同

248
我想知道在HTML5中是否有iFrames的替代方法。我的意思是,在不使用iFrame的情况下,能否将跨域的HTML注入到网页中。
12个回答

124

基本上有四种方法可以将HTML嵌入到网页中:

  • <iframe> 标签的内容完全处于与您的页面不同的上下文中。虽然这通常是一个很好的特性,而且它在浏览器版本之间也最兼容,但它也会带来额外的挑战(将框架的大小缩小到其内容很困难,非常令人沮丧地对/出脚本,几乎不可能进行样式设置)。
  • AJAX。正如这里展示的解决方案所证明的那样,您可以使用XMLHttpRequest对象检索数据并将其注入到您的页面中。这并不理想,因为它依赖于脚本技术,从而使执行变得更加缓慢和复杂,还有其他缺点
  • Hacks。这个问题中提到的一些方法并不是非常可靠。
  • HTML5 Web Components。Web组件的一部分HTML导入允许将HTML文档捆绑在其他HTML文档中。其中包括HTMLCSSJavaScript或任何其他.html文件可以包含的内容。这使它成为一个伟大的解决方案,具有许多有趣的用例:将应用程序拆分为可分发的构建块组件,更好地管理依赖项以避免冗余,代码组织等。这里是一个微不足道的例子:

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

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

本地兼容性仍然存在问题,但是您可以使用polyfill来使其在最新的浏览器中工作。

您可以在此处此处了解更多信息。


4
HTML5网络组件很有趣。 - Krishna Srihari
1
我知道这篇文章有点旧了,但我想发表一下评论:关于AJAX,“它不是理想的,因为它依赖于脚本技术”...那么,使用脚本有什么问题吗? AJAX是这些选择中无可争议的领先者,并且正在迅速成为标准。 - nmg49
29
很遗憾,HTML Imports 功能现在已经过时了。https://developer.mozilla.org/en-US/docs/Web/Web_Components/HTML_Imports - Gman
有没有新的方法来实现这个? - user7075574
5
iFrames的另一个重要缺点是,许多网站将“X-Frame-Options”设置为“sameorigin”,并且拒绝连接,因此你的iFrame将保持空白。这种情况下,没有办法修复。 - Igor P.

74

您可以使用对象和嵌入,如下所示:

<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>

这不是新的,但仍然有效。但我不确定它是否具有相同的功能。


非常感谢,这让我避免了加载 Facebooks Like Box 的 SDK。 - Techagesite

61

object 是 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>

您也可以尝试embed标签:

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

重复-

由于目前StackOverflow已关闭显示外部URL内容的支持,因此运行代码片段不会显示任何内容。但对于您的网站,它将完美地工作。


6
两者都没有避开我对iframe的问题,比如安全策略。 - SeanMC
6
请记住,大多数现代浏览器已经不支持浏览器插件,因此如果您希望您的网站能在一般用户的浏览器上正常运行,依赖于<embed>并不明智。建议使用其他替代方案。 - Neeraj
1
你能纠正 perfectly 的拼写吗? - Fennekin
感谢@Fennekin发现拼写错误,已经更新。 - Abrar Jahin

56
不,没有等价物。 <iframe> 元素在HTML5中仍然有效。根据您需要的确切交互,可能会有不同的API。例如,有postMessage方法,允许您实现跨域javascript交互。但如果您想显示跨域HTML内容(使用CSS进行样式化,并使用javascript进行交互),iframe仍然是一个很好的方法。

3
我需要从谷歌加载内容,但谷歌不能以 iframe 的形式嵌入,有什么替代方法? - Mike
19
@Mike,另一个选择是使用你想要使用的服务的API。谷歌为其大多数服务提供RESTful API。 - Darin Dimitrov

21

如果您想这样做并且能够控制提供基本页面或内容的服务器,则可以使用跨域资源共享 (http://www.w3.org/TR/access-control/),允许客户端JavaScript通过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();

现在是整个操作的关键,您需要为服务器编写代码,以提供 Access-Control-Allow-Origin 标头,指定您希望客户端代码能够通过 XMLHttpRequest() 访问哪些域。以下是您可以在页面顶部包含的PHP代码示例,以便将这些标头发送给客户端:

<?php
  header('Access-Control-Allow-Origin: http://api.google.com');
  header('Access-Control-Allow-Origin: http://some.example.com');
?>

17

12

一个iframe仍然是下载跨域视觉内容的最佳方式。使用AJAX,您可以从网页中下载HTML并将其放在一个div中(正如其他人所提到的),但更大的问题是安全性。使用iframe,您将能够加载跨域内容,但无法操纵它,因为内容实际上并不属于您。另一方面,使用AJAX,您可以操纵任何您能够下载的内容,但其他域的服务器必须以允许您开始下载的方式进行设置。很多时候,您无法访问其他域的配置,即使您可以访问,除非您经常进行这种配置,否则可能会引起头痛。在这种情况下,iframe可以是更容易的替代方案。

正如其他人所提到的,您还可以使用嵌入标签和对象标签,但这并不一定比iframe更先进或更新。

HTML5已经更多地采用了Web API来获取来自跨域的信息。通常,Web API只返回数据而不是HTML。


1
这并不是一个真正的答案,但肯定是一个“好知道”的东西。 - Stef Geysels

6
我创建了一个 Node 模块来解决这个问题: node-iframe-replacement。您提供父站点的源 URL 和要注入内容的 CSS 选择器,它会将两者融合在一起。父站点的更改每5分钟会被捕获。
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
    });
});

该源代码包含一个将内容注入到BBC新闻主页的工作示例

可参考示例输出


嗨,我已经尝试过了,似乎不再起作用了? - Hunter

2
您可以使用XMLHttpRequest将页面加载到div(或页面上的任何其他元素)中。 一个示例函数如下所示:
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();
}

如果你的服务器有能力,你也可以使用PHP来完成这个任务,但既然你要求一个HTML5方法,那么这应该就是你所需要的。

5
大多数浏览器都会阻止使用XMLHttpRequest从其他域加载内容。 - Erik Terenius
5
楼主希望进行跨域操作,这个回答不符合要求。 - Teoman shipahi

0
在您自己的网站页面中加载另一个网站页面的关键问题是安全性。有跨站点安全策略定义,如果另一个网站将其设置为严格的同源策略,则您将无法直接在iframe中加载它。因此,为了找到替代方案,他们必须能够绕过此安全策略限制,即使在未来,如果WSC引入任何新组件,它也会具有类似的安全限制。
目前,绕过此限制的最佳方法是在逻辑上模拟正常页面访问,这意味着AJAX +服务器端访问可能是一个不错的选择。您可以在服务器端设置一些代理,获取页面内容并将其加载到iframe中。这种方法可行,但并不完美,因为如果内容中有任何链接或图像,则可能无法访问。
通常,如果您尝试在自己的iframe中加载页面,则需要检查页面是否可以在iframe中加载。这篇post文章提供了如何进行检查的一些指南。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接