项目场景:
在开发过程中,会遇到图片预览,视频预览,图文预览等等。最近就遇到了一个图文预览的问题,后端同学直接返回图文html文件,而前端需要对于文件中的一些元素做处理。
问题描述
首先就是返回的html文件未作编码设置,导致页面获取的数据直接是乱码;其次是html页面的图片路径属于相对路径,这对于直接应用到系统中来说,肯定是不行的,因为我们的系统中不存在这种相对路径下的图片文件,导致图片无法展示。
文本乱码示例:
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/4a46aae24037028cf81780b4c96aa942.png)
图片不展示示例:
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/38adaa78e6758223faae66281b5e2358.png)
原因分析:
问题的分析:
1.html文件乱码问题:这个是接口返回的html地址,乱码问题很有可能是源文件未作编码设置【<meta charset="utf-8" http-equiv="Content-Type" content="text/html">
源文件少了后面两个属性(http-equiv="Content-Type" content="text/html"
)】
2.图片预览失败问题:html地址是可以地址栏直接预览的,但是里面的图片路径是相对路径,当前系统下没有此类图片文件,自然是不会展示的了
解决方案:
1.html乱码问题解决:
该问题通过blob解决的,就是在获取到在线可读的html文件地址后,将其使用get请求,携带(responseType:'blob'
)获取文件后,再通过iframe标签包含展示
html代码:
<div class="iframe-container">
<iframe
v-if="iframeUrl"
id="iframeContainer"
:src="iframeUrl"
frameborder="0"
@load="deliverToken">
您当前的浏览器不支持页面上的功能,请升级您当前的浏览器版本或使用谷歌浏览器访问当前页面
</iframe>
</div>
js代码:
const url = '浏览器可查看的html地址'
const blob = await preview(url)
this.iframeUrl = URL.createObjectURL(blob)
请求:
// 预览功能-请求html文件
export function preview(path) {
return axiosAjax({
url: path,
method: 'get',
responseType: 'blob'
})
.then((data) => {
var blob = new Blob([data], {
type: 'text/html'
})
return blob
})
}
2.html中图片路径为相对路径的解决方案就是,通过js将图片的src修改为浏览器可读的绝对路径,比如:
https://img1.baidu.com/it/u=554809536,2732110137&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=560
。
这个就要从iframe的@load
方法入手了。load方法在html模块代码可以看见
注意:document.getElementById('iframeContainer').contentWindow这里,返回的是iframe的window对象,所以后面可以接着调用document方法,再接着调用querySelectorAll。那么就可以对iframe里面的元素进行操作了。
deliverToken(obj) {
this.$nextTick(() => {
const url = '浏览器可查看的html地址'
const startUrl = url.slice(0, url.lastIndexOf('/'))//截取前半部分路径
const obj = document.getElementById('iframeContainer').contentWindow
const imgs = obj.document.querySelectorAll('.blockcenter')//获取iframe下的img标签(带calss的)
imgs.forEach((element, i) => {
imgs[i].src = startUrl + '/' + element.dataset.ckfinderSrcbackup//遍历图片标签,拼接修改src路径
imgs[i].parentNode.style.textAlign = 'center'//设置图片父盒子居中
})
})
},