我正在使用此库进行消息传递。
我的背景脚本是这样的
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);
});