欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vue2項目如何使用pdfjs-dist解析pdf

 更新時間:2025年05月23日 09:42:12   作者:驢肉板燒鳳梨牛肉堡  
這篇文章主要為大家詳細介紹了Vue2項目如何使用pdfjs-dist解析pdf相關(guān),文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

先說結(jié)論

使用pdfjs-dist的2.7.570版本

使用pdfjs-dist的2.7.570版本的es5產(chǎn)物,該版本的es5的build產(chǎn)物沒有特殊寫法,對vue.config.js、babel.config.js的兼容性最好,不需要額外再下載其他插件,比如可選鏈插件等

引用方式

import * as pdfjsLib from 'pdfjs-dist/es5/build/pdf'
import pdfWorker from 'pdfjs-dist/es5/build/pdf.worker.entry'

pdfjsLib.GlobalWorkerOptions.workerSrc = pdfWorker
pdfjsLib.GlobalWorkerOptions.isEvalSupported = false // 關(guān)閉 eval 支持(防止漏洞)

背景

某天,產(chǎn)品同事發(fā)現(xiàn)C端的資質(zhì)展示頁面(H5)的圖片渲染有問題,經(jīng)排查發(fā)現(xiàn)有些鏈接是.pdf結(jié)尾的pdf文件,最后導(dǎo)致某些機型無法正常渲染。如下圖所示

這里有個小點: ios機型會把pdf渲染出來1頁,安卓機型無法渲染pdf

遇到問題時的思考

這種情況在線上是否多,如果量級不多,個人感覺可以嘗試后端進行解析PDF轉(zhuǎn)成圖片,在更新數(shù)據(jù)庫。但這需要結(jié)合業(yè)務(wù)系統(tǒng)來看,因為這是“資質(zhì)文件”,所以得保證業(yè)務(wù)系統(tǒng)在這方面的功能是怎么樣的,是只能上傳圖片還是pdf,還是都能,不過這是后面分析才得到的結(jié)果

后端是否好解決,這需要和后端溝通

需求

能夠根據(jù)pdf鏈接展示出他的所有頁數(shù)內(nèi)容,不失真,能在各個機型的web-view中運行,如安卓app、ios的app、支付小程序、微信小程序。

只做pdf解析預(yù)覽功能,不需要額外功能,把內(nèi)容轉(zhuǎn)成圖片即可。

盡量做到不修改vue.config.js、babel.config.js來解決這個問題,理想情況就是新增一個組件,然后對應(yīng)頁面判斷是鏈接,最后使用下就好了。畢竟這是老項目,這些可不能亂動。

前期開發(fā)工作

與后端溝通,結(jié)果是后端不好解決,只能交給前端來解決

先問gpt,具體方案和關(guān)鍵依賴,可能的坑點

搜索gpt,根據(jù)得到的關(guān)鍵依賴(pdfjs-dist),了解他的issue、坑點、demo等

順便搜下相關(guān)文章,但發(fā)現(xiàn)質(zhì)量都挺一般的,數(shù)量有點少,于是就參考gpt的,其次就是pdfjs-dist的文檔有點難看懂

具體實施

下載 pdfjs-dist,下載時下的是最新版本,5.x.x

新建pdf-viewr.vue組件

復(fù)制gpt給我的代碼

運行項目

# gpt給的案例
import * as pdfjsLib from 'pdfjs-dist/build/pdf'
import pdfWorker from 'pdfjs-dist/build/pdf.worker.entry'
pdfjsLib.GlobalWorkerOptions.workerSrc = pdfWorker

// 解析過程省略,主要核心是引用方式的問題

踩坑之旅

依照上述實施行為,結(jié)果就是直接報錯,運行不了,于是我就開始了我的漫長踩坑之旅

我的依賴&版本

  • node: 12.22.22
  • @vue/cli: ^3.12.0
  • babel-core: 7.0.0-bridge.0
  • vue: 2.6.x

版本問題

使用pdfjs-dist遇到了非常多的版本兼容性問題,由于用的是最新版本,有很多寫法,和我的對不上,于是我的想法是降版本,但一開始不知道降到多少,畢竟有1549個版本,想法是問ai,但ai回答出來的版本還是不太行,于是我就打算換個方式,找找有沒有現(xiàn)成的封裝好的組件

這里找到的是vue-pdf,這個組件是用pdfjs-dist+vue2的,我大喜過望,馬上下載使用,寫起來很快呀,但新的問題已然埋下

vue-pdf問題

  • issue數(shù)量特別多,只能說慎用,一共235個
  • 這個組件在打包上線后,會無法正常加載出來,導(dǎo)致對應(yīng)頁面白屏。根據(jù)gpt的說法是可能丟失了pdfjs-dist,然后我就去找原因,這種情況先找issue,我在vue-pdf的issue中看到了有人遇到了同樣的問題,然后我在某個issue中,看到了這么一句話:使用2.7.570版本。

于是我順藤摸瓜,找到pdfjs-dist的版本記錄,找到他的內(nèi)容是什么,然后我就發(fā)現(xiàn)了一個讓我很興奮的點:

這個依賴的有build和es5的build產(chǎn)物!?。?,這是最關(guān)鍵的,他的其他版本我看了幾個,我發(fā)現(xiàn)沒有es5的打包產(chǎn)物

用build的產(chǎn)物仍然存在特殊寫法,比如可選鏈,因為我的項目沒有可選鏈的babel插件,所以仍然不能用

但是es5的產(chǎn)物沒有特殊寫法,所以理論上用這個就能解決了,因為引用報錯的問題是語法相關(guān)的兼容性問題,我又不想新增babel插件、loader依賴等

最后在我使用了這個版本后,修改了原先AI提供的案例中的引用方式,于是項目正常跑了起來,這里就不使用vue-pdf了,使用pdfjs-dist,用它來解析,然后轉(zhuǎn)圖片。

對比如下:

# 前
import * as pdfjsLib from 'pdfjs-dist/build/pdf'
import pdfWorker from 'pdfjs-dist/build/pdf.worker.entry'
pdfjsLib.GlobalWorkerOptions.workerSrc = pdfWorker

# 后
import * as pdfjsLib from 'pdfjs-dist/es5/build/pdf'
import pdfWorker from 'pdfjs-dist/es5/build/pdf.worker.entry'
pdfjsLib.GlobalWorkerOptions.workerSrc = pdfWorker

病毒問題

病毒問題也是看vue-pdf的issue才知道的

根據(jù)報告鏈接所提供的方案就是

pdfjsLib.GlobalWorkerOptions.isEvalSupported = false // 關(guān)閉 eval 支持(防止漏洞)

小結(jié)

為了解決pdfjs-dist在vue2的老項目的兼容性問題,最終方案就是使用pdfjs-dist@2.7.570,這樣就不用影響到之前的vue.config.js、babel.config.js相關(guān)配置了。

這個過程解決兼容問題,費時費力,還以為無法解決了,不過皇天不負(fù)苦心人,這個問題還是被解決了,所以記錄下。

后續(xù)計劃

自己打包高版本(5.x.x)的pdfjs-dist來適應(yīng)內(nèi)部項目

研究vue-pdf打包上線白屏問題

接入vue3項目

分頁加載優(yōu)化,大文件優(yōu)化

代碼

pdf解析預(yù)覽組件

<template>
  <div class="pdf-viewer">
    <van-loading v-if="loading" type="spinner" size="32px" vertical>加載中</van-loading>
    <div v-else>
      <div v-if="error" class="fallback">
        <p>當(dāng)前信息無法加載,您可以<a :href="pdfUrl" target="_blank">點擊查看</a></p>
      </div>
      <div v-else>
        <div v-for="(page, index) in pages" :key="index" class="pdf-page">
          <img :src="page" :alt="'pdf ' + (index + 1)" class="pdf-image">
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { Loading } from 'vant'

// ? 使用pdfjs-dist的2.7.570版本的es5產(chǎn)物,該版本的es5的build產(chǎn)物沒有特殊寫法,對本項目vue.config.js、babel.config.js的兼容性最好
import * as pdfjsLib from 'pdfjs-dist/es5/build/pdf'
import pdfWorker from 'pdfjs-dist/es5/build/pdf.worker.entry'

pdfjsLib.GlobalWorkerOptions.workerSrc = pdfWorker
pdfjsLib.GlobalWorkerOptions.isEvalSupported = false // 關(guān)閉 eval 支持(防止漏洞)// 漏洞鏈接: https://www.venustech.com.cn/new_type/aqtg/20240514/27492.html

export default {
  name: 'pdf-viewer',
  props: {
    pdfUrl: {
      type: String,
      required: true,
    },
  },
  components: {
    [Loading.name]: Loading,
  },
  data() {
    return {
      pages: [],
      loading: true,
      error: false,
    }
  },
  mounted() {
    this.loadPdf()
  },
  methods: {
    async loadPdf() {
      try {
        const loadingTask = pdfjsLib.getDocument(this.pdfUrl)
        const pdf = await loadingTask.promise
        const pageImages = []

        for (let pageNum = 1; pageNum <= pdf.numPages; pageNum++) {
          const page = await pdf.getPage(pageNum)
          const viewport = page.getViewport({ scale: 2 }) // scale 調(diào)大可提高清晰度

          const canvas = document.createElement('canvas')
          const context = canvas.getContext('2d')
          canvas.width = viewport.width
          canvas.height = viewport.height

          await page.render({ canvasContext: context, viewport }).promise
          pageImages.push(canvas.toDataURL())
        }

        this.pages = pageImages
        this.loading = false
      } catch (e) {
        console.error('PDF 加載失敗:', e)
        this.error = true
        this.loading = false
      }
    },
  },
}
</script>

<style lang="stylus" scoped>
.pdf-viewer {
  width: 100%;
  overflow-x: hidden;
}
.pdf-image {
  width: 100%;
  display: block;
  object-fit: contain;
}
.fallback {
  text-align: center;
  color: #999;
  font-size: 14px;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;

  a {
    color: #007aff;
    text-decoration: underline;
  }
}
</style>

鏈接類型判斷

    // 判斷文件類型(擴展名優(yōu)先,fallback 為 HEAD)
    async detectFileType(url) {
      // 1. 特殊 scheme 優(yōu)先判斷
      if (url.startsWith('data:image/')) return 'image'
      if (url.startsWith('data:application/pdf')) return 'pdf'
      if (url.startsWith('blob:')) return 'unknown'

      // 2. 擴展名判斷(寬松匹配)
      if (/\.(jpe?g|png|gif|bmp|webp|svg)([\?#].*)?$/i.test(url)) return 'image'
      if (/\.pdf([\?#].*)?$/i.test(url)) return 'pdf'

      // 3. 嘗試發(fā) HEAD 請求獲取 content-type
      try {
        const res = await axios.head(url) // ? 支付寶小程序如果遇到404鏈接會導(dǎo)致頁面白屏,微信、安卓不會
        const contentType = res.headers['content-type'] || ''
        if (contentType.includes('image/')) return 'image'
        if (contentType.includes('application/pdf')) return 'pdf'
      } catch (e) {
        console.warn('鏈接類型獲取失敗:', url, e.message)
      }

      return 'unknown'
    }

到此這篇關(guān)于Vue2項目如何使用pdfjs-dist解析pdf的文章就介紹到這了,更多相關(guān)Vue2解析pdf內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue日期時間工具類詳解

    vue日期時間工具類詳解

    這篇文章主要為大家詳細介紹了vue日期時間工具類,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • Vue淺拷貝和深拷貝實現(xiàn)方案

    Vue淺拷貝和深拷貝實現(xiàn)方案

    在理解淺拷貝和深拷貝淺前,必須先理解基本數(shù)據(jù)類型和引用數(shù)據(jù)類型的區(qū)別,這篇文章主要介紹了Vue淺拷貝和深拷貝實現(xiàn)方案及區(qū)別對比分析,需要的朋友可以參考下
    2023-03-03
  • vue項目如何引入json數(shù)據(jù)

    vue項目如何引入json數(shù)據(jù)

    這篇文章主要介紹了vue項目如何引入json數(shù)據(jù),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • vue登錄頁面回車執(zhí)行事件@keyup.enter.native問題

    vue登錄頁面回車執(zhí)行事件@keyup.enter.native問題

    這篇文章主要介紹了vue登錄頁面回車執(zhí)行事件@keyup.enter.native問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • Vue3?如何通過虛擬DOM更新頁面詳解

    Vue3?如何通過虛擬DOM更新頁面詳解

    這篇文章主要為大家介紹了Vue3?如何通過虛擬DOM更新頁面詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-09-09
  • vue之el-tree懶加載數(shù)據(jù)并且實現(xiàn)樹的過濾問題

    vue之el-tree懶加載數(shù)據(jù)并且實現(xiàn)樹的過濾問題

    這篇文章主要介紹了vue之el-tree懶加載數(shù)據(jù)并且實現(xiàn)樹的過濾問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • 一文教你如何一個Vue指令搞定函數(shù)防抖

    一文教你如何一個Vue指令搞定函數(shù)防抖

    防抖(Debounce)在前端開發(fā)中是一種常用的技術(shù),它的作用是限制某個操作在短時間內(nèi)的頻繁觸發(fā),下面我們就來看看如何一個Vue指令搞定函數(shù)防抖吧
    2024-02-02
  • vue引入ueditor及node后臺配置詳解

    vue引入ueditor及node后臺配置詳解

    這篇文章主要介紹了vue引入ueditor及node后臺配置詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-01-01
  • vue3中g(shù)etCurrentInstance不推薦使用及在<script?setup>中獲取全局內(nèi)容的三種方式

    vue3中g(shù)etCurrentInstance不推薦使用及在<script?setup>中獲取全局內(nèi)容的三種方式

    這篇文章主要給大家介紹了關(guān)于vue3中g(shù)etCurrentInstance不推薦使用及在<script?setup>中獲取全局內(nèi)容的三種方式,文中通過介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2024-02-02
  • Vue取消Axios發(fā)出的請求

    Vue取消Axios發(fā)出的請求

    axios 是一個基于 promise 的 HTTP 庫,可以用在瀏覽器和 node.js 中。首先需要知道:axios不是一種新的技術(shù)。axios 是一個基于Promise 用于瀏覽器和 nodejs 的 HTTP 客戶端,本質(zhì)上也是對原生XHR的封裝,只不過它是Promise的實現(xiàn)版本,符合最新的ES規(guī)范
    2022-09-09

最新評論