Я хочу написать расширение Chrome, которое по сути должно передавать информацию (1) из сценария content.js
в background.js
, где оно отправляет информацию на внешний сервер Node.js, а затем (2) background.js
должно пересылать ответ сервера на popup.js
, поэтому его можно отобразить в popup.html. Этот процесс должен происходить каждый раз при посещении страницы.
Я добился того, что информация полностью передается в popup.js, но я использую chrome.runtime.sendMessage
каждый раз для передачи информации от контента к фону и оттуда во всплывающее окно, и в каждом случае я использую chrome.runtime.onMessage.addListener
для получения сообщения. Однако теперь popup.js получает как сообщение, которое content.js передает в background.js, так и сообщение, правильно переданное из background.js в popup.js. Я просто хочу, чтобы последнее сообщение было получено popup.js.
Это мой background.js
код:
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
console.info("received from content.js:\n" + request.content_message);
sendResponse({check: "to content.js: background recieved content_message"});
fetch('http://localhost:3000/message', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ message: request.content_message})
})
.then(response => response.json())
.then(data => {
console.info(data.response);
const to_popup = data.response;
chrome.runtime.sendMessage({res: to_popup }, function(response) {
console.info(response.popup_answer);
});
})
.catch(error => {
console.error('Error:', error);
});
}
);
А это мой popup.js
код:
chrome.runtime.onMessage.addListener( function(request, sender, sendResponse) {
alert(JSON.stringify({request}));
sendResponse({popup_answer: "to background: popup recieved message"});
});
Я сравнил свой код с ответом, представленным здесьздесь . Я посмотрел сообщение в доках и там написано:
Если несколько страниц прослушивают события onMessage, только первая, вызвавшая sendResponse() для определенного события, сможет отправить ответ. Все остальные ответы на это событие будут игнорироваться.
Кажется, это касается только случая ответа, но не получения сообщений.
Я думал о
Мне кажется, что должен быть лучший и разумный способ. Есть ли у вас какие-либо предложения для меня? Спасибо!
@woxxom Спасибо! Но мне нужен фоновый скрипт для подключения и получения ответа от сервера, так как это должно происходить автоматически. Когда я реализовал это во всплывающем окне, это больше не будет автоматическим, или есть обходной путь?
Код, который вы показали до сих пор, не делает ничего из того, что должно быть в фоновом сценарии. Все можно сделать во всплывающем окне, потому что вы все равно хотите отобразить данные, поэтому onMessage будет запускаться только тогда, когда всплывающее окно отображается.
@woxxom Спасибо, я сделал это сейчас аналогично тому, что вы предложили, и все работает отлично :) Это мне действительно помогло!
Вы можете использовать что-то вроде этого:
// constants.js
export const backgroundScriptCommands = {
FETCH_DATA_FROM_SERVER: 'fetch-data-from-server',
...
};
export const popupCommands = {
PRINT_DATA: 'print-data',
...
};
// Your content-script.js
chrome.runtime.sendMessage({ type: backgroundScriptCommands.FETCH_DATA_FROM_SERVER });
// Your background-script.js
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
switch (request.type) {
case backgroundScriptCommands.FETCH_DATA_FROM_SERVER:
// do something
}
});
// Your popup.js
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
switch (request.type) {
case popupCommands.PRINT_DATA:
// do something
}
});
Таким образом вы сможете понять, кому адресовано сообщение, и просто не реагировать, если сообщение адресовано, например background-script
.
Однако здесь есть несколько моментов, на которые стоит обратить ваше внимание:
chrome.runtime.onMessage
прослушиватель в вашем popup.js
будет работать только после того, как пользователь нажмет на всплывающий значок. И перестанет работать, если всплывающее окно закроется. Возможно, вы можете просто использовать popup.js
, чтобы поработать, как написал @woxxom в комментариях, или просто отправить сообщение service-worker
→ chrome.runtime.sendMessage({ type: backgroundScriptCommands.FETCH_DATA_FROM_SERVER })
. И еще: если вы попытаетесь отправить сообщение с background-script
на popup.js
, если оно неактивно, вы получите исключение.
Большое спасибо! Я сделал это сейчас, как предложил @woxxom. Вы очень хорошо заметили, что popup.js работает сразу после того, как пользователь нажимает на значок всплывающего окна. Мне это не подошло бы, так что большое спасибо за подсказку!
Нет необходимости в фоновом скрипте: просто делайте все в onMessage во всплывающем окне.