使用iframe遇到的问题及解决
记录一下使用iframe遇到的bug
动态的iframe src与返回的bug
场景:iframe嵌入页面,有多个tab,切换tab修改iframe的src,显示不同的页面
<ul>
<li
v-for="tab in tabList"
:key="tab.tabName"
class="tab-item"
:class="{ activeTab: activeTabName === tab.tabName }"
@click="changeTab(tab)"
>
{{ tab.tabName }}
</li>
</ul>
<iframe
:src="iframePath"
frameborder="0"
width="100%"
height="600"
id="iframe"
</iframe>
data() {
return {
tabList: [
{
path: "http://www.test.com/firstPage.html",
tabName: "hover页面",
},
{
path: "http://www.test.com/secondPage.html",
tabName: "关系图谱",
},
{
path: "http://www.test.com/thirdPage.html",
tabName: "echart页面 ",
},
],
activeTabName: "hover页面",
iframePath: "http://www.test.com/firstPage.html",
};
},
methods: {
changeTab(tab) {
if(this.iframePath===tab.path) return
this.activeTabName = tab.tabName;
this.iframePath = tab.path;
},
},
操作步骤:切换tab,然后点击浏览器的返回,就会出现tab与页面内容对不上的情况
原因:修改iframe的src,window.history历史记录中也会添加一条记录(动态切换iframe的src会导致增加一条iframe的历史浏览记录)
解决方案:在切换src的时候把iframe给销毁再重新创建就行了。这样就是一个新的iframe,不会触发他的变更操作,也就不会往window.history中存入记录
这种写法不太优雅,但是可以实现不添加历史记录:
let parent = document.querySelector(".iframe-parent");
let child = document.getElementById("iframe");
let newElement = document.createElement("iframe");
newElement.src = tab.path;
newElement.id = "iframe";
parent.replaceChild(newElement, child);
由于vue中的key更改时会重新渲染这个组件,给iframe添加一个key,这样每次切换时,key不一样就会重新创建一个iframe,销毁原来的iframe,这样也能做到不添加历史记录:
<!-- 加了key会重新渲染iframe,不会往history中添加记录了 -->
<iframe
:src="iframePath"
frameborder="0"
width="100%"
height="600"
id="iframe"
:key="iframePath"
></iframe>
http与https的嵌入的问题
将已开发好的页面资源(http)通过iframe嵌入https的协议下,内容没有加载出来,结果发现控制台报错
Mixed Content: The page at 'https://' was loaded over HTTPS, but requested an insecure frame 'http://'. This request has been blocked; the content must be served over HTTPS.
混合内容:在某些情况下,HTTPS 站点也可能包含一些使用明文 HTTP 协议加载的元素,这将形成一个称为混合内容的情形,有时也称为“HTTP over HTTPS”
1》主动混合内容:通过 HTTP 提供的元素或依赖项能够与整个网页交互并对网页进行更改,如js或api请求
2》被动混合内容(显示混合内容):未加密的 HTTP 内容仅限于站点上封装的并且无法与页面其余部分交互的元素,如图片与视频;攻击者可以阻止或替换通过 HTTP 加载的图片,但无法修改页面的其余部分
大多数现代 Web 浏览器都在开发者控制台中提供针对混合内容的警告,并且阻止危险程度较高的混合内容类型。各种浏览器都有自己的一套规则,但一般而言,主动混合内容更有可能会被阻止,被动混合内容仅在开发者控制台中向用户提供混合内容警告
解决方案:
方案1:将外壳链接降为http
方案2:将iframe的内容升级成https协议
方案3:nginx代理
第一种和第二种很容易被否决,因为要申请,流程比较麻烦