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

Chrome Extension V3:Content.js与Background.js通信故障求助

Chrome Extension V3 科研论文搜索工具报错排查与修复

核心问题拆解

  1. Background 消息监听方式完全错误:V3 中 Service Worker 不能用 self.addEventListener("message") 监听扩展内部消息,必须用官方指定的 chrome.runtime.onMessage.addListener,这直接导致 Background 收不到任何消息,所以控制台无输出。
  2. Popup 脚本引用逻辑混乱:把用于注入网页的 content.js 直接塞到 Popup 里,二者运行上下文完全不同,Popup 应该用独立的脚本文件(比如 popup.js)。
  3. 异步请求未等待就返回结果:Background 里用 forEach 发起 fetch 请求后立刻发回结果,此时所有异步请求还没跑完,results 是空数组。
  4. 消息回复方式错误:Popup 通过 chrome.runtime.sendMessage 发消息,Background 应该用回调里的 sendResponse 回复,而非 chrome.tabs.sendMessage(这是给网页里的内容脚本发消息的方法)。

修复后的完整代码

1. manifest.json 调整权限与脚本配置

{
  "manifest_version": 3,
  "name": "Get Free Copy",
  "description": "搜索各平台的免费科研论文副本",
  "version": "1.0",
  "permissions": ["tabs"],
  "host_permissions": ["https://*/*"],
  "background": {
    "service_worker": "background.js"
  },
  "action": {
    "default_title": "Get Free Copy",
    "default_popup": "popup.html"
  },
  "content_scripts": [
    {
      "matches": ["https://*/*"],
      "js": ["content.js"]
    }
  ]
}

2. popup.html 替换脚本引用+基础美化

<!DOCTYPE html>
<html>
<head>
  <title>Get Free Copy</title>
  <style>
    body {width: 300px; padding: 12px;}
    #search-input {width: 72%; padding: 5px; border: 1px solid #ddd; border-radius: 4px;}
    button {padding: 5px 10px; border: none; border-radius: 4px; background: #1a73e8; color: white; cursor: pointer;}
    #search-results {margin-top: 15px;}
    #search-results a {display: block; margin: 6px 0; color: #1a73e8; text-decoration: none;}
    #search-results a:hover {text-decoration: underline;}
  </style>
</head>
<body>
  <form id="search-form">
    <input type="text" id="search-input" placeholder="输入论文标题">
    <button type="submit">搜索</button>
  </form>
  <div id="search-results"></div>
  <script src="popup.js"></script>
</body>
</html>

3. popup.js 独立处理 Popup 逻辑

document.getElementById("search-form").addEventListener("submit", async function(event) {
  event.preventDefault();
  const searchInput = document.getElementById("search-input").value.trim();
  if (!searchInput) return;

  const resultsContainer = document.getElementById("search-results");
  resultsContainer.innerHTML = '<p>搜索中...</p>';

  try {
    const response = await chrome.runtime.sendMessage({ type: "search", title: searchInput });
    resultsContainer.innerHTML = "";
    
    if (response.results.length === 0) {
      resultsContainer.innerHTML = '<p>未找到相关结果</p>';
      return;
    }

    response.results.forEach(result => {
      const resultElement = document.createElement("a");
      resultElement.href = result.url;
      resultElement.target = "_blank";
      resultElement.textContent = result.title;
      resultsContainer.appendChild(resultElement);
    });
  } catch (error) {
    resultsContainer.innerHTML = `<p>搜索出错:${error.message}</p>`;
    console.error("搜索失败:", error);
  }
});

4. background.js 修复消息监听与异步逻辑

// 正确监听扩展内部消息
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  if (request.type === "search") {
    const title = request.title;
    const title2 = title.replace(/ /g, "+");
    const queries = [
      { url: `https://www.ncbi.nlm.nih.gov/pmc/?term=${title}`, title: "NCBI PMC" },
      { url: `https://www.biorxiv.org/search/${title}`, title: "bioRxiv" },
      { url: `https://www.medrxiv.org/search/${title}`, title: "medRxiv" },
      { url: `https://www.google.com/search?q=${title2}+filetype:pdf`, title: "PDF搜索" }
    ];

    // 用 Promise.all 等待所有异步请求完成
    const fetchPromises = queries.map(query => {
      return fetch(query.url)
        .then(response => {
          if (!response.ok) throw new Error(`请求失败`);
          return response.text();
        })
        .then(() => {
          // 这里可以添加HTML解析逻辑,暂时直接返回平台链接
          // 若要使用cheerio,需通过打包工具(如Webpack)将其引入Service Worker
          return { title: query.title, url: query.url };
        })
        .catch(() => {
          return { title: `${query.title} (搜索失败)`, url: "#" };
        });
    });

    // 所有请求完成后回复消息
    Promise.all(fetchPromises).then(results => {
      sendResponse({ results: results });
    });

    // 返回true告知Chrome等待异步回复
    return true;
  }
});

额外提示

  • 查看 Background 日志时,要在扩展管理页面点击「服务工作者」→「检查」,打开专属控制台,不是网页的控制台。
  • 部分平台有反爬机制,直接 fetch 可能返回403,可以给请求加个 headers: { 'User-Agent': navigator.userAgent } 模拟浏览器请求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 18:05:17