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

Chrome扩展消息通信异常:google_login请求报错,clicked_browser_action正常

排查Chrome扩展消息发送错误:Receiving end does not exist

我在Chrome扩展中,从popup对应的main.js向background.js发送消息时,遇到错误:Uncaught (in promise) Error: Could not establish connection. Receiving end does not exist.
发送的两种消息里,clicked_browser_action能正常工作,但google_login触发上述错误。


main.js

function processPage(root) {
    document.getElementById('submit-btn').addEventListener('click', submitButtonClicked);
    document.getElementById('google-signin-btn').addEventListener('click', googleSiginButtonClicked);
    chrome.runtime.onMessage.addListener(receiveMessage);
}

function appendText(text) {
    let node = document.getElementById('web-content');
    node.innerHTML += text;
}

function submitButtonClicked() {
    appendText("submit button clicked");
    sendMessage({txt: "clicked_browser_action"});
}

function googleSiginButtonClicked() {
    console.log("sending login message");
    sendMessage({txt: "google_login"});
}

function receiveMessage(request, sender, sendResponse) {
    if (request.txt === "page_content") {
        appendText(request.content);
    }
}

// 当前实现:向活跃标签页发送消息
function sendMessage(response) {
    let params = {active: true, currentWindow: true};
    chrome.tabs.query(params, function(tabs) {
        chrome.tabs.sendMessage(tabs[0].id, response);
    });
}

if (document.readyState === "complete") {
    processPage(document.body);
} else {
    window['onload'] = function () {
        processPage(document.body);
    }
}

background.js

let user_signed_in = false;

const CLIENT_ID = "MY_CLIENT_ID"
const REDIRECT_URI = chrome.identity.getRedirectURL("oauth2");

function create_oauth() {
    let auth_url = `https://accounts.google.com/o/oauth2/v2/auth?`
  
    var auth_params = {
      client_id: CLIENT_ID,
      redirect_uri: REDIRECT_URI,
      response_type: 'token',
      scope: "https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile openid",
    };
  
    const url = new URLSearchParams(Object.entries(auth_params));
    auth_url += url;
    return auth_url;
}

function googleLoginListener(request, sender, sendResponse) {
    console.log("googleLoginListener: ", request);
    if (request.txt === 'google_login') {
      if (user_signed_in) {
        return;
      } else {
        chrome.identity.launchWebAuthFlow({
          url: create_oauth(),
          interactive: true
        }, function (redirect_uri) {
          sendResponse('success')
        })
      }
    }
}

function processPage() {
    console.log("background service active");
    chrome.runtime.onMessage.addListener(googleLoginListener);
}

processPage();

main.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="main.js"></script>
</head>
<body>
    <div style="width: 200px; height: 200px;">
        Displaying web content below
    </div>
    <div id="web-content"></div>
    <button id="submit-btn">PRINT CONTENT</button>
    <button id="google-signin-btn">GOOGLE SIGN_IN</button>
</body>
</html>

问题根源与修复

1. 消息发送API使用错误

你的sendMessage函数调用了chrome.tabs.sendMessage,这是给当前标签页的content script发消息的API,但你要通信的目标是background.js,应该使用chrome.runtime.sendMessage直接与background建立通信。

clicked_browser_action看似正常,是因为当前标签页的content script中大概率监听了这个消息,而google_login没有对应的content script监听,因此触发“接收端不存在”的错误。

修改后的sendMessage函数:

// 直接向background发送消息
function sendMessage(response) {
    chrome.runtime.sendMessage(response, (res) => {
        if (chrome.runtime.lastError) {
            console.error(chrome.runtime.lastError);
        } else {
            console.log("收到background响应:", res);
        }
    });
}

2. 异步响应的通道保持

background中的googleLoginListener调用了异步APIchrome.identity.launchWebAuthFlow,需要在监听函数中返回true,告知Chrome保留消息通道直到sendResponse被调用,否则会提前断开连接导致错误。

修改后的googleLoginListener:

function googleLoginListener(request, sender, sendResponse) {
    console.log("googleLoginListener: ", request);
    if (request.txt === 'google_login') {
      if (user_signed_in) {
        sendResponse('already signed in');
        return;
      } else {
        chrome.identity.launchWebAuthFlow({
          url: create_oauth(),
          interactive: true
        }, function (redirect_uri) {
          user_signed_in = true;
          sendResponse('success')
        });
        // 返回true表示异步响应,保持通道开放
        return true;
      }
    }
}

3. 验证manifest权限

确保manifest.json中声明了必要的权限和OAuth2配置:

{
  "permissions": ["identity", "tabs"],
  "oauth2": {
    "client_id": "你的CLIENT_ID",
    "scopes": [
      "https://www.googleapis.com/auth/userinfo.email",
      "https://www.googleapis.com/auth/userinfo.profile",
      "openid"
    ]
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 07:05:21