利用patch-package补丁,解决H5预览PDF时电子签章不显示问题

利用patch-package补丁,解决H5预览PDF时电子签章不显示问题

一、问题描述

在生产环境中,遇到了一个紧急的技术问题:用户在移动端H5页面上查看电子票时,PDF文件预览功能正常,但其中的电子签章未能正常显示。这一问题直接影响了用户验证电子票真实性的体验,需要迅速解决。

二、问题排查与定位

经过仔细排查,确定了问题的根源:后端返回的PDF文件为Base64格式,前端使用pdf.js-dist库进行渲染时,由于库作者的某些原因,电子签章功能被默认屏蔽。在本地开发环境中,可以通过直接修改源码来解除这一屏蔽,但这种方法无法直接应用到生产环境,因为每次重新安装依赖时,修改的内容都会被覆盖。

三、解决方案设计与实施

为了在生产环境中修复这一问题,同时确保未来更新依赖时修改不会被覆盖,采取以下策略解决此问题:

1、引入patch-package工具:通过npm安装patch-package,这是一个允许开发者在应用npm install命令后,对node_modules中的代码进行补丁修改的npm钩子。使用它,可以安全地对pdf.js-dist库进行必要的修改,并确保这些修改在后续依赖更新时仍能保持。

js 复制代码
npm i patch-package // 安装补丁工具

2、配置package.json:在项目的package.json文件中,添加了"postinstall"脚本,用于在每次安装依赖后自动运行patch-package命令,确保补丁被正确应用。

3、创建补丁文件:使用npx patch-package pdfjs-dist命令,手动为pdfjs-dist库创建了补丁文件。执行此命令后,项目根目录下自动生成了一个patches文件夹,其中包含了一个针对pdfjs-dist库的补丁文件,该文件详细记录了在node_modules中对pdf.js-dist库所做的修改。

js 复制代码
npx patch-package pdfjs-dist // 在修复node_modules的源码后执行改指令

四、代码实现以及问题截图

vue 复制代码
<template>
<!-- 查看电子票 -->
<div class="nucleicAcidTestMain">
  <e-headers class="nucleicAcidTestNav" Transparency>查看电子票</e-headers>
  <div class="pdfList" />
  <div class="tips">长按可下载电子票</div>
  </div>
</template>
<script>
  import PDFJS from 'pdfjs-dist';
  export default {
    mounted() {
      this.pdfBase64(url); //url为base64格式的pdf
    },
    methods: {
      // 解码
      pdfBase64(url) {
        let base64 = url.replace(new RegExp('data:application/pdf;base64,', 'g'), '').replace(/[\n\r]/g, '');
        let decodedBase64 = atob(base64); //使用浏览器自带的方法解码
        this.pdfToCanvas({ data: decodedBase64 });
      },
      // pdf转canvas图片
      async pdfToCanvas(url) {
        this.canDown = true;
        let pdfList = document.querySelector('.pdfList');
        let pdf = await PDFJS.getDocument(url); //返回一个pdf对象
        let pages = pdf.numPages; //声明一个pages变量等于当前pdf文件的页数
        for (let i = 1; i <= pages; i++) {
          //循环页数
          let canvas = document.createElement('canvas');
          let page = await pdf.getPage(i); //调用getPage方法传入当前循环的页数,返回一个page对象
          let scale = 5; //缩放倍数,1表示原始大小(倍数越大越清晰)
          let viewport = page.getViewport(scale);
          let context = canvas.getContext('2d'); //创建绘制canvas的对象
          canvas.height = viewport.height; //定义canvas高和宽
          canvas.width = viewport.width;
          canvas.style.width = '100%';
          let renderContext = { canvasContext: context, viewport: viewport };
          await page.render(renderContext);
          const imgUrl = canvas.toDataURL('image/png', 1.0); // canvas转为图片,实现下载
          const img = document.createElement('img');
          img.src = imgUrl;
          img.style.width = '100%';
          pdfList.appendChild(img);
        }
      },
      returnPage() {
        this.$router.go(-1);
      }
    }
  };
</script>

五、总结

成功解决了移动端H5电子票PDF预览中的电子签章不显示问题。通过引入patch-package工具,可以在生产环境中有效地对第三方库进行补丁修改,但是此种补丁方法要求对应依赖版本,也就是说项目所对应的PDFJS库版本更改后,很可能会导致补丁不生效或者需要重新生成补丁。所有一般采用固定版本号对应补丁。

需求考虑项目是否强依赖于库更新。

本文由博客一文多发平台 OpenWrite 发布!

相关推荐
Amodoro4 个月前
微信小程序预览PDF、H5预览PDF、网页预览PDF,并添加专属文字水印
pdf.js·pdf预览·h5预览pdf·微信小程序预览pdf·pdf.js的使用
陆康永1 年前
使用patch-package保存node_modules包修改
npm·patch-package