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

Chrome扩展内容脚本正确加载pdf.js外部库的方法求助

如何在Chrome扩展内容脚本中正确加载pdf.js并处理在线PDF

嘿,我来帮你搞定这个问题!先拆解一下你之前遇到的两个错误,再一步步给出解决方案:

为什么之前的方法会报错?

1. Manifest中直接用CDN链接加载pdf.js失败

Chrome扩展对content_scripts里的JS文件有严格限制:必须是扩展包内的本地资源,不能直接引用外部CDN链接。这是出于安全考虑,防止恶意外部脚本注入,所以你的manifest.json会加载失败。

2. 内容脚本中调用chrome.tabs.executeScript报错

内容脚本运行在和页面隔离的沙箱环境里,没有权限使用chrome.tabsAPI——这个API只能在后台脚本(background)、弹出页(popup)或者选项页里调用,所以你在内容脚本里访问chrome.tabs会得到undefined,进而触发TypeError。


正确的解决方案步骤

第一步:下载pdf.js到扩展本地

先去pdf.js官方仓库下载编译好的核心文件:pdf.js和pdf.worker.js,把它们放到你的扩展目录里,比如新建一个libs文件夹来存放,这样路径就是./libs/pdf.js和./libs/pdf.worker.js。

第二步:调整Manifest配置

根据你用的Manifest版本(V2/V3),更新权限和基础配置:

Manifest V3 示例:

{
  "manifest_version": 3,
  "name": "你的扩展名称",
  "version": "1.0",
  "permissions": ["activeTab", "scripting", "tabs"],
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["content.js"]
    }
  ],
  "background": {
    "service_worker": "background.js"
  },
  "action": {
    "default_popup": "popup.html"
  }
}

Manifest V2 示例:

{
  "manifest_version": 2,
  "name": "你的扩展名称",
  "version": "1.0",
  "permissions": ["activeTab", "tabs"],
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["content.js"]
    }
  ],
  "background": {
    "scripts": ["background.js"]
  },
  "browser_action": {
    "default_popup": "popup.html"
  }
}

第三步:修改弹窗脚本(popup.js)

把之前的jQuery代码换成原生JS(或者保留jQuery,但确保你引入了jQuery文件),监听复选框变化并发送消息:

document.getElementById('check_id').addEventListener('change', function() {
  const msg = { pdf: this.checked ? 'yes' : 'no' };
  chrome.tabs.query({ currentWindow: true, active: true }, tabs => {
    chrome.tabs.sendMessage(tabs[0].id, msg);
  });
});

第四步:更新内容脚本(content.js)

内容脚本不再直接加载pdf.js,而是先判断页面是否为PDF,再请求后台脚本加载资源:

chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  if (message.pdf === 'yes') {
    // 先验证当前页面是否是PDF
    if (document.contentType === 'application/pdf') {
      // 向后台请求加载pdf.js
      chrome.runtime.sendMessage({ action: 'loadPdfJs' }, () => {
        // 资源加载完成后处理PDF
        handlePdf();
      });
    } else {
      console.log('当前打开的不是PDF页面哦');
    }
  } else {
    // 处理普通HTML页面的逻辑
    console.log('开始处理普通HTML页面');
  }
});

function handlePdf() {
  // 手动指定pdf.worker.js的路径(关键!防止worker加载失败)
  PDFJS.GlobalWorkerOptions.workerSrc = chrome.runtime.getURL('libs/pdf.worker.js');
  
  // 加载当前页面的PDF
  PDFJS.getDocument({ url: window.location.href }).then(doc => {
    console.log(`这个PDF一共有${doc.numPages}页`);
    // 这里可以添加你的PDF处理逻辑,比如提取文本、渲染页面等
  }).catch(err => {
    console.error('加载PDF失败:', err);
  });
}

第五步:后台脚本处理资源加载

Manifest V3(background.js,service worker):

chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  if (message.action === 'loadPdfJs') {
    // 动态注入本地的pdf.js和pdf.worker.js
    chrome.scripting.executeScript({
      target: { tabId: sender.tab.id },
      files: ['libs/pdf.js', 'libs/pdf.worker.js']
    }, () => {
      sendResponse();
    });
    return true; // 标记为异步响应
  }
});

Manifest V2(background.js):

chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  if (message.action === 'loadPdfJs') {
    // 先加载pdf.js,再加载worker
    chrome.tabs.executeScript(sender.tab.id, { file: 'libs/pdf.js' }, () => {
      chrome.tabs.executeScript(sender.tab.id, { file: 'libs/pdf.worker.js' }, () => {
        sendResponse();
      });
    });
    return true; // 标记为异步响应
  }
});

几个关键注意事项

  • 确保pdf.js和pdf.worker.js的路径和你Manifest/代码里写的一致,路径错误会导致加载失败。
  • 在Chrome内置的PDF viewer中,document.contentType会返回application/pdf,可以用这个来判断页面类型。
  • 必须用chrome.runtime.getURL()获取扩展内资源的正确路径,尤其是pdf.worker.js,否则会因为跨域问题加载失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 09:15:49