#javascript #reactjs #google-chrome-extension
#javascript #reactjs #google-chrome-расширение
Вопрос:
В данный момент я изучаю React и хотел попробовать создать расширение Chrome с его помощью. К сожалению, я не могу заставить обмен сообщениями работать между моим компонентом и фоновым скриптом. Что я делаю не так? 🙂
Вот код, который должен обмениваться информацией между фоновым скриптом и компонентом React:
***** Реагирующий компонент *****
import * as React from "react";
import { useState, useEffect } from "react";
import WatchListEntry from "./WatchListEntry";
const WatchList = () => {
const [watchListEntries, setWatchListEntries] = useState<any>([]);
useEffect(() => {
chrome.runtime.onMessage.addListener((message) => {
console.log(message);
switch (message.type) {
case "NEW_ARTICLE":
setWatchListEntries([...watchListEntries, message.article]);
console.log(message.data);
break;
default:
break;
}
});
}),
[];
return (
<>
<h1>Watchlist</h1>
<ul>
{watchListEntries.map((watchListEntry: any) => {
<WatchListEntry data={watchListEntry} />;
})}
</ul>
</>
);
};
export default WatchList;
***** background.js *****
import axios from "axios";
chrome.runtime.onInstalled.addListener(function () {
chrome.contextMenus.create({
id: "watchListMenu",
title: "Libri Watchlist",
contexts: ["page", "link"],
});
chrome.contextMenus.create({
id: "addToWatchlist",
parentId: "watchListMenu",
title: "Test-Funktion-fuer-Links",
contexts: ["page", "link"],
});
});
chrome.contextMenus.onClicked.addListener((info) => {
if (info.menuItemId === "addToWatchlist") {
addToWatchlist(info);
}
});
//Wie kann info für TypeScript verbessert werden? Erst einmal den Typ any gewählt.
const addToWatchlist = async (info: any) => {
let articleId = getArticleId(info);
let articleInfos = await getArticleInfos(articleId);
let { ean, title, authorList } = articleInfos.result.articleAttributeView;
/* let ean = titleData.ean;
let title = titleData.title;
let author = titleData.authorList; */
console.log(
`console.log from addToWatchlist: ${ean}, ${title}, ${authorList}, ${articleId}`
);
chrome.runtime.sendMessage({
type: "NEW_ARTICLE",
article: { ean, title, authorList },
});
};
const getArticleInfos = async (articleId: string) => {
//Kann die Abfrage immer über chakryotik.buchhandlung.de geschehen? Oder müssen aufgrund unterschiedlicher Bestände die diversen Buchhändler abgefragt werden?
try {
const { data } = await axios.get(
`https://...some API call...`
);
return data;
} catch (error) {
console.log(error);
}
};
const getArticleId = (info: any) => {
let url = info.linkUrl;
if (url === undefined) {
url = info.pageUrl;
}
let regExpForLink = /article/d /;
let regExpForArticleId = /d /;
let [match] = url.match(regExpForLink);
let [articleId] = match.match(regExpForArticleId);
return articleId;
};
***** manifest.json *****
{
"name": "Libri Watchlist",
"description": "React Chrome Extension für Shopline",
"manifest_version": 2,
"version": "1.0.0",
"icons": {
"16": "watchlist.png",
"48": "watchlist.png",
"128": "watchlist.png"
},
"browser_action": {
"default_icon": {
"16": "watchlist.png",
"48": "watchlist.png"
},
"default_popup": "popup.html"
},
"background": {
"scripts": ["background.js"],
"persistent": false
},
"content_scripts": [
{
"matches": ["*://*/*"],
"js": ["content.js"]
}
],
"permissions": ["storage", "contextMenus", "https://*/"]
}
С консолью.войдите в функцию addToWatchlist, я вижу, что информация получена правильно. К сожалению, сообщение не получено в моем компоненте. Есть идеи? 🙂
Большое вам спасибо за вашу помощь!
Стефан
Комментарии:
1. Если код реакции находится во всплывающем окне browser_action (или page_action), то он запускается только тогда, когда отображается всплывающее окно, и не запускается, когда не отображается. В этом случае вы можете сохранить данные в
chrome.storage.local
илиchrome.storage.sync
и просто прочитать их в начале скрипта popup.2. @wOxxOm Спасибо тебе! Я действительно не понимаю, что делают browser_action / page_action. Но я постараюсь решить свою проблему с помощью chrome.storage.local. 🙂
3. @wOxxOm Извините, что снова беспокою вас! Должен ли я в этом случае вызывать API из скрипта содержимого?
4. Похоже, мое предположение, возможно, было ошибочным. Чтобы избежать этого, вы всегда должны показывать свой manifest.json и объяснять, где выполняется каждый фрагмент кода. Для отправки сообщений в сценарии содержимого вы должны использовать chrome.tabs.SendMessage, см. Документацию .
5. Еще раз спасибо, @wOxxOm! Я только что добавил manifest.json в свой первый пост. Поскольку я не понимаю всего взаимодействия между фоном, контентом и остальным, мне трудно объяснить проблему. 🙂