You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用react-pdf v7.3.3偶现Worker was terminated错误,求排查思路

react-pdf@7.3.3 偶发 "Worker was terminated" 错误排查方案

使用react-pdf v7.3.3渲染PDF时,页面加载阶段偶发以下错误:

unpkg.com/pdfjs-dist@3.6.172/build/pdf.worker.min.js:22 Uncaught (in promise) Error: Worker was terminated
    at ensureNotTerminated (unpkg.com/pdfjs-dist@3.6.172/build/pdf.worker.min.js:22:2053)
    at onFailure (unpkg.com/pdfjs-dist@3.6.172/build/pdf.worker.min.js:22:10071)

已确认pdf.worker.min.js与pdf.js版本匹配,且最小复现示例无法重现该问题,核心代码如下:

App组件

import React from 'react';
import Previewer from './previewer/Previewer';

const App: React.FC = () => {
  return (
    <div>
      <Previewer pdfUrl={"https://arxiv.org/pdf/2304.09103.pdf"}></Previewer>
    </div>
  );
}

export default App;

Previewer组件核心逻辑

import React, { useState } from 'react';
import { Document, Page, pdfjs } from 'react-pdf';
pdfjs.GlobalWorkerOptions.workerSrc = `//unpkg.com/pdfjs-dist@${pdfjs.version}/build/pdf.worker.min.js`;

const Previewer: React.FC<{pdfUrl: string | undefined}> = (props) => {
    const [pdfScale, setPdfScale] = useState<number>(1);
    const [numPages, setNumPages] = useState<number>();

    // 注意:此处cMapUrl使用了与pdfjs.version不一致的版本
    const options = {
        cMapUrl: 'https://cdn.jsdelivr.net/npm/pdfjs-dist@3.9.179/cmaps/',
    };

    const onDocumentLoadSuccess = (pdf: any) => {
        setNumPages(pdf.numPages);
    }

    // 一次性渲染所有PDF页面
    const renderPages = (totalPageNum: number | undefined) => {
        if (!totalPageNum || totalPageNum < 1) return;
        const tagList: JSX.Element[] = [];
        for (let i = 1; i <= totalPageNum; i++) {
            tagList.push(
                <Page key={i} scale={pdfScale} pageNumber={i} ></Page>
            );
        }
        return tagList;
    }

    return (
        <div>
            <Document options={options} file={props.pdfUrl} onLoadSuccess={onDocumentLoadSuccess}>
                {renderPages(numPages)}
            </Document>
        </div>
    );
}

export default Previewer;

可能的解决方向

1. 统一pdfjs相关资源版本

你的代码中cMapUrl使用的是pdfjs-dist@3.9.179,但react-pdf依赖的pdfjs-dist是3.6.172,版本不一致会导致内部逻辑冲突,修改为对应版本:

const options = {
    cMapUrl: `https://cdn.jsdelivr.net/npm/pdfjs-dist@${pdfjs.version}/cmaps/`,
};

2. 避免批量渲染所有页面

一次性渲染所有Page组件会瞬间向worker发送大量渲染请求,超出浏览器worker资源限制导致被终止。改为分页渲染(仅渲染当前可见区域的页面):

const [pageNumber, setPageNumber] = useState<number>(1);

// 只渲染当前页及前后1页
const renderPages = (totalPageNum: number | undefined) => {
    if (!totalPageNum || totalPageNum < 1) return;
    const tagList: JSX.Element[] = [];
    const startPage = Math.max(1, pageNumber - 1);
    const endPage = Math.min(totalPageNum, pageNumber + 1);
    for (let i = startPage; i <= endPage; i++) {
        tagList.push(
            <Page key={i} scale={pdfScale} pageNumber={i} ></Page>
        );
    }
    return tagList;
}

3. 改用本地worker资源

CDN加载worker可能因网络波动、缓存问题导致初始化不完整,将pdf.worker.min.js下载到项目静态资源目录,修改workerSrc指向本地路径:

pdfjs.GlobalWorkerOptions.workerSrc = '/static/pdf.worker.min.js';

4. 组件卸载时清理worker实例

组件在PDF加载过程中被卸载时,未完成的worker任务会抛出终止错误,添加卸载时的清理逻辑:

import { useRef, useEffect } from 'react';

const Previewer: React.FC<{pdfUrl: string | undefined}> = (props) => {
    const documentRef = useRef<any>(null);

    useEffect(() => {
        return () => {
            if (documentRef.current) {
                documentRef.current.destroy(); // 销毁worker实例
            }
        };
    }, []);

    // ...其他逻辑

    return (
        <div>
            <Document ref={documentRef} options={options} file={props.pdfUrl} onLoadSuccess={onDocumentLoadSuccess}>
                {renderPages(numPages)}
            </Document>
        </div>
    );
}

内容的提问来源于stack exchange,提问作者Dolphin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 12:12:32