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

Chrome扩展消息发送失败:无法建立连接,接收端不存在

解决Chrome扩展深色模式切换的连接错误问题

针对你遇到的「Error sending message: Could not establish connection. Receiving end does not exist」错误,结合你的代码和配置,以下是具体排查和修复方案:

1. 移除冗余的背景页注入逻辑

你的Background.ts中通过chrome.action.onClicked注入内容脚本的代码完全多余——因为manifest.json已经配置了content_scripts自动注入,且当扩展有default_popup时,点击图标只会打开弹窗,不会触发action.onClicked事件。直接删除这段代码即可,避免逻辑混淆。

2. 修正内容脚本的路径配置

当前manifest.json中content_scripts的js路径是["src/content/content.js"],但Vite + crx插件打包后,实际输出的内容脚本路径并非这个相对路径。需要调整为打包后的正确路径:

{
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["content.js"]
    }
  ]
}

同时修改vite.config.ts,确保内容脚本打包后输出到扩展根目录:

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { crx } from "@crxjs/vite-plugin";
import manifest from "./src/manifest.json";
import path from 'path'

export default defineConfig({
  plugins: [react(), crx({manifest})],
  build: {
    rollupOptions: {
      input: {
        background: "src/background/background.ts",
        content: "src/content/content.ts",
      },
      output: {
        entryFileNames: "[name].js", // 确保输出文件名为content.js、background.js
        chunkFileNames: "[name].js",
        assetFileNames: "[name].[ext]"
      }
    },
  },
  resolve: {
    alias: { '@': path.resolve(__dirname, './src') },
  },
})

3. 确保内容脚本正确加载的验证步骤

  • 打开目标网站的开发者工具(F12),切换到Console标签,搜索✅ Content script loaded:
    • 如果未找到该日志,说明脚本未注入,检查扩展的「站点访问权限」是否设置为「在所有网站上」;同时确认目标页面不是chrome://、about://等特殊页面(这类页面无法注入内容脚本)。
    • 如果日志存在,说明脚本已加载,问题出在消息发送逻辑。

4. 优化弹窗的消息发送逻辑

在弹窗发送消息前,先处理内容脚本未注入的情况,添加失败时的自动注入逻辑:

import { useEffect, useState } from "react";

const Popup = () => {
  const [isDarkMode, setIsDarkMode] = useState(false);

  useEffect(() => {
    chrome.storage.sync.get("darkMode", (data) => {
      setIsDarkMode(data.darkMode ?? false);
    });
  }, []);

  const toggleDarkMode = () => {
    chrome.tabs.query({ active: true, currentWindow: true }, async (tabs) => {
      const activeTab = tabs[0];
      if (!activeTab?.id) {
        console.error("❌ No active tab found.");
        alert("Error: No active tab found.");
        return;
      }

      try {
        // 先尝试发送消息
        const response = await chrome.tabs.sendMessage(activeTab.id, { action: "toggle-dark-mode" });
        console.log("✅ Response from content script:", response);
        setIsDarkMode(response.darkMode);
        chrome.storage.sync.set({ darkMode: response.darkMode });
      } catch (error) {
        // 发送失败,说明脚本未注入,手动注入后重试
        console.log("🔄 Injecting content script...");
        await chrome.scripting.executeScript({
          target: { tabId: activeTab.id },
          files: ["content.js"]
        });
        // 注入后再次发送消息
        const response = await chrome.tabs.sendMessage(activeTab.id, { action: "toggle-dark-mode" });
        console.log("✅ Response after injection:", response);
        setIsDarkMode(response.darkMode);
        chrome.storage.sync.set({ darkMode: response.darkMode });
      }
    });
  };

  return (
    <div className="w-48 p-4 flex flex-col items-center bg-white shadow-lg rounded-lg">
      <h2 className="text-lg font-semibold mb-2">Dark Mode</h2>
      <button 
        className={`px-4 py-2 rounded-md text-white ${ isDarkMode ? "bg-gray-800" : "bg-blue-500" }`} 
        onClick={toggleDarkMode}
      >
        {isDarkMode ? "Disable Dark Mode" : "Enable Dark Mode"}
      </button>
    </div>
  );
};

export default Popup;

5. 同步存储状态与页面状态

原代码中弹窗的isDarkMode状态仅从存储读取,但未与页面实际状态同步。上述优化后的代码中,在收到内容脚本的响应后,会更新弹窗状态并同步到存储,确保状态一致。


内容的提问来源于stack exchange,提问作者Akhil kumar srivastava

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 06:43:21