从后台脚本到内容脚本发送消息时,使用扩展chrome/消息时出现错误



我正在使用此库进行消息传递。

我的背景脚本是这样的

import { sendUrlInfo, waitForUrl } from 'utils/messaging';
import URL from 'url-parse';
chrome.webNavigation.onHistoryStateUpdated.addListener((details) => {
const url = new URL(details.url);
console.log('sending', url.hostname, url.pathname);
sendUrlInfo(new URL(details.url));
});
chrome.webNavigation.onCompleted.addListener((details) => {
if (details.url !== 'about:blank') {
const url = new URL(details.url);
console.log('sending', url.hostname, url.pathname);
sendUrlInfo(new URL(details.url));
}
});

根据文档,我有message.js如下所示

import { getMessage } from '@extend-chrome/messages';
import URL from 'url-parse';
const messageTypes = {
URL_INFO: 'URL_INFO',
};
export const [sendUrlInfo, urlStream, waitForUrl] = getMessage<URL>(
messageTypes.URL_INFO,
);

和现在的内容脚本我已经写在反应所以当组件被挂载时,我试图订阅流

import React, { useState, useEffect, useRef } from 'react';
import Editor from 'content/components/Editor';
import Opener from 'content/components/Opener';
import { urlStream, waitForUrl } from 'utils/messaging';
const Main: React.FC = () => {
const [isOpen, setIsOpen] = useState(false);
const [showContent, setShowContent] = useState(false);
const editorRef = useRef<HTMLTextAreaElement | null>(null);
useEffect(() => {
console.log('MOunted');
urlStream.subscribe(([url]) => {
console.log('Received', url.hostname, url.pathname);
if (url.hostname === 'www.youtube.com' && url.pathname === '/watch') {
if (!showContent) setShowContent(true);
} else {
if (showContent) setShowContent(false);
}
});
}, []);
useEffect(() => {
document.addEventListener('keydown', onKeyPress);
return () => {
document.removeEventListener('keydown', onKeyPress);
};
});
const onKeyPress = (e: KeyboardEvent) => {
if (e.ctrlKey && e.which === 192) {
e.preventDefault();
setIsOpen(!isOpen);
}
};
if (!showContent) return <></>;
return (
<>
<div>test</div>
<Opener isOpen={isOpen} onClick={() => setIsOpen(true)} />
<Editor
isOpen={isOpen}
ref={editorRef}
onClose={() => setIsOpen(false)}
/>
</>
);
};
export default Main;

我在后台脚本控制台得到的错误是

无法建立连接。接收端不存在

我认为就我所知,后台脚本正在尝试发送msg,但内容脚本可观察对象尚未订阅。作为内容脚本在页面加载后运行。如果是这个问题,有什么方法可以正确使用这个库吗?

BTW如果我们使用像这样的普通chrome api,这是有效的

chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
chrome.tabs.sendMessage(
tabs[0].id,
message,
function () {
console.log("msg sent")     
}
);
});

并使用onMessage来接收消息

背景页需要知道我们正在向选项卡发送消息。除非定义了options.tabId,否则sendUrlInfo使用chrome.runtime.sendMessage发送消息。

在后台脚本中为sendUrlInfo添加options参数:

chrome.webNavigation.onHistoryStateUpdated.addListener((details) => {
const url = new URL(details.url);
console.log('sending', url.hostname, url.pathname);
const options = { tabId: details.tabId }; // Add options.tabId here
sendUrlInfo(new URL(details.url), options);
});

最新更新