“我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第2篇文章,点击查看活动详情”
背景
前端日常开发过程中,有时候会遇到 pdf浏览器预览 的需求,后端直接返回了 blob文件流,前端如何实现文件在浏览器打开预览哪? 本文主要介绍对应功能的实现。
实现思路
-
前端发起网络请求,指定响应类型,拿到后端返回的文件流,文件名。
-
利用 new Blob() 创造一个 Blob 对象
-
利用 URL.createObjectURL(blob) 创造url地址。
-
浏览器打开即可。
注意点:先开空窗口,然后最后赋值url, 防止浏览器拦截窗口不能打开
函数封装
import axios from 'axios';
/**
* 预览pdf, ie 不支持预览,表现为下载
* 获取文件, 文件返回的为blob流
* @param {*} method 请求方式
* @param {*} url 接口地址
* @param {*} data 请求参数
* @param {*} fileName 文件名
*/
export default async function pdfPreview(method, url, data, fileName) {
let open;
if ('download' in document.createElement("a")) { //非ie
open = window.open(); //此处先开窗口,防止被浏览器拦截不能直接打开
}
try {
await axios({
url: url,
method: method,
data: JSON.stringify(data),
responseType: 'blob', //指定blob
headers: {
'Content-Type':'application/json;',
// token 等其它所需请求头
}
}).then((res)=> {
const content = res.data;
const contentType = res.headers['content-type'] || 'application/pdf';
const blob = new Blob([content], {type:contentType});
// 文件名一般后端会返回,调用方法时不需要传入。如果不返回,需要前端传入
// 具体在header里面那个字段返回需要协商, 此处只是一种方式,可自行修改。
if (!fileName) { //未传入fileName, 从header里面取
if (res.headers['fileName']) {
fileName = decodeURI(res.headers['fileName']);
}
}
if ('download' in document.createElement("a")) {
const href = URL.createObjectURL(blob);
open.location = href;
} else {
navigator.msSaveBlob(blob, fileName);
}
});
} catch(e) {
}
}
- 注意先开窗口
- 注意headers需要添加所需请求头
- 注意文件名字的处理,与后端约定好即可。
- ie 不支持预览,ie也退出舞台了,所以无碍。
函数调用
调用对应函数,传入对应参数即可。
pdfPreview('get', url)
总结
按照对应思路实现即可,每天进步一点点。
点赞评论支持是更新的动力,jym 动动小手支持下吧!