30行JS代码 实现 pdf 浏览器预览功能

730 阅读2分钟

“我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第2篇文章,点击查看活动详情

背景

前端日常开发过程中,有时候会遇到 pdf浏览器预览 的需求,后端直接返回了 blob文件流,前端如何实现文件在浏览器打开预览哪? 本文主要介绍对应功能的实现。

image.png

实现思路

  1. 前端发起网络请求,指定响应类型,拿到后端返回的文件流,文件名。

  2. 利用 new Blob() 创造一个 Blob 对象

  3. 利用 URL.createObjectURL(blob) 创造url地址。

  4. 浏览器打开即可。

    注意点:先开空窗口,然后最后赋值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) {
  }
}
  1. 注意先开窗口
  2. 注意headers需要添加所需请求头
  3. 注意文件名字的处理,与后端约定好即可。
  4. ie 不支持预览,ie也退出舞台了,所以无碍。

函数调用

调用对应函数,传入对应参数即可。

pdfPreview('get', url)

总结

按照对应思路实现即可,每天进步一点点。

点赞评论支持是更新的动力,jym 动动小手支持下吧!