VUE使用 iframe 嵌入网页
- 基础使用
<iframe>标签生成一个指定区域,在该区域中嵌入其他网页。它是一个容器元素,如果浏览器不支持<iframe>,就会显示内部的子元素。
<iframe src=Example Domain
width="100%" height="500" frameborder="0"
allowfullscreen sandbox>
<p><a href="https://www.example.com">点击打开嵌入页面</a></p>
</iframe>
嵌入页面的地址:Example Domain,
显示区域的宽度是100%,高度是500px。
如果当前浏览器不支持<iframe>,则会显示一个链接,让用户点击。
- <iframe>的属性
allowfullscreen:允许嵌入的网页全屏显示,需要全屏 API 的支持,请参考相关的 JavaScript 教程。
frameborder:是否绘制边框,0为不绘制,1为绘制(默认值)。建议尽量少用这个属性,而是在 CSS 里面设置样式。
src:嵌入的网页的 URL。
width:显示区域的宽度。
height:显示区域的高度。
sandbox:设置嵌入的网页的权限,详见下文。
importance:浏览器下载嵌入的网页的优先级,可以设置三个值。high表示高优先级,low表示低优先级,auto表示由浏览器自行决定。
name:内嵌窗口的名称,可以用于<a>、<form>、<base>的target属性。
referrerpolicy:请求嵌入网页时,HTTP 请求的Referer字段的设置。参见<a>标签的介绍。
- sandbox 属性
嵌入的网页默认具有正常权限,比如执行脚本、提交表单、弹出窗口等。但若嵌入的网页是第三方网页,对方的操作可能存在安全风险。为了限制<iframe>的风险,HTML 提供了sandbox属性,允许设置嵌入的网页的权限,等同于提供了一个隔离层,即“沙箱”。
sandbox可以当作布尔属性使用,表示打开所有限制。
<iframe src="https://www.example.com" sandbox>
</iframe>
sandbox属性可以设置具体的值,表示逐项打开限制。未设置某一项,就表示不具有该权限。
allow-forms:允许提交表单。
allow-modals:允许提示框,即允许执行window.alert()等会产生弹出提示框的 JavaScript 方法。
allow-popups:允许嵌入的网页使用window.open()方法弹出窗口。
allow-popups-to-escape-sandbox:允许弹出窗口不受沙箱的限制。
allow-orientation-lock:允许嵌入的网页用脚本锁定屏幕的方向,即横屏或竖屏。
allow-pointer-lock:允许嵌入的网页使用 Pointer Lock API,锁定鼠标的移动。
allow-presentation:允许嵌入的网页使用 Presentation API。
allow-same-origin:不打开该项限制,将使得所有加载的网页都视为跨域。
allow-scripts:允许嵌入的网页运行脚本(但不创建弹出窗口)。
allow-storage-access-by-user-activation:允许在用户激动的情况下,嵌入的网页通过 Storage Access API 访问父窗口的储存。
allow-top-navigation:允许嵌入的网页对顶级窗口进行导航。
allow-top-navigation-by-user-activation:允许嵌入的网页对顶级窗口进行导航,但必须由用户激活。
allow-downloads-without-user-activation:允许在没有用户激活的情况下,嵌入的网页启动下载。
注意,不要同时设置allow-scripts和allow-same-origin属性,这将使得嵌入的网页可以改变或删除sandbox属性。
- iframe在项目中的使用
当iframe嵌入的网页与使用iframe的页面不属于同原页面,会存在跨域等一系列问题,针对项目开发中出现过的问题,进行分析总结
- iframe嵌套第三方页面跨域带cookie问题
背景:业务初始化完成后,可以点击跳转到iDaaS页面;
跳转地址获取逻辑:取当前项目网关地址,然后拼接iDaaS网关路径得到跳转路径
设计实现的方案为:使用cookie里面设置的网关的ip端口进行跳转
问题描述:
此方案需要解决技术点:iframe嵌套第三方页面跨域带cookie问题
由于两个项目为独立的项目,如果初始化这个项目想要跨域拿到页面设置的cookie
解决:
方法一:将两个页面都代理到同一地址就不存在跨域问题了
在配置文件nginx.conf中
完成配置后,
192.168.40.26:18080访问192.168.40.26:20080时,nginx将会代理转发到访问192.168.40.67:8090;
192.168.40.26:18080访问192.168.40.26:10024时,nginx将会代理转发到访问192.168.40.67:10024。
如果有多个server需要nginx转发,可以并行写多个server
方法二:使用samesite属性
在 iframe 跨域的场景下,无论是服务器,还是内嵌的页面,如果要写入 Cookie,都需要增加 SameSite=None;Secure;
开发建议:
1.禁用浏览器samsite属性/或降低版本(目前仅chorme存在)
2.保证同源策略cookie共享(保证ip或域名一致)
3.设置response.setHeader(“Set-Cookie”, “HttpOnly;Secure;SameSite=None”),需设置https证书
4.不使用cookie共享会话,使用token实现
- 使用iframe嵌入动态路径,路由的代理相关问题
问题:项目嵌入该工程时使用iframe嵌入,嵌入的路径是动态的,路由的代理会产生问题,运维功能嵌入其他平台时,路径也是动态的同样也需要配置
解决:
- 项目嵌iframe 在request请求中,通过Window.location.href拿到容器云当前路径,然后和接口进行拼接
- 运维功能嵌入。在嵌入之前,拿到当前浏览器路径然后拼接,这样在获取接口的时候就可以代理到正确的地址了
- 使用iframe标签时,如何阻止嵌入的页面跳转(页面重定向)
问题:页面嵌入之后展示被嵌入项目的配置页面,但页面会自动跳转至一个新的页面同时覆盖之前的页面
难点:被嵌入项目会重定向至新页面,但要求不允许页面重定向
解决:给iframe标签设置相应属性:
allow-same-origin 允许 iframe 内容被视为与包含文档有相同的来源
allow-forms 允许表单提交
allow-scripts 允许脚本执行
allow-popups 允许弹窗
<iframe :src="pannelInfo.pannelURL" id="web" frameborder="0" class="web-frame"
security="restricted"
sandbox="allow-same-origin allow-top-navigation allow-forms allow-scripts"></iframe>