Я построил расширение для Chrome, и меня поражает состояние гонки, с которым мне нужна помощь.
Если вы видите ответ расширение chrome: совместное использование объекта между скриптами содержимого и фоновым скриптом говорит нам, что вы не можете совместно использовать переменную между контентом и фоновыми скриптами.
Моя цель - создать уникальный идентификатор для каждой вкладки браузера, а затем поделиться им между content.js
и background.js
. Затем мне нужно использовать это значение в javascript, внедренном в контент, как объяснено в этом ответе: В расширениях Chrome, вы можете заставить некоторый javascript быть введенным перед всем?
Единственный способ, которым я смог выяснить, как это сделать, это выполнить следующий асинхронный код, тогда я просто использую идентификатор вкладки в качестве уникального идентификатора:
content.js
await pingBackground();
async function pingBackground() {
var info;
await new Promise(function (resolve, reject) {
chrome.runtime.sendMessage({ type: 1 }, function (response) {
if (response !== undefined) {
info = response;
resolve();
}
else {
reject();
}
});
});
console.log("Id is " + info.id);
}
background.js
chrome.runtime.onMessage.addListener(messageHandler);
function messageHandler(message, sender, reply) {
switch (message.type) {
case 1:
reply({ 'id': sender['tab'].id, 'active': true });
break;
}
}
manifest.json
{
"name": "oogi",
"version": "0.1",
"manifest_version": 2,
"background": {
"scripts": [
"common.js",
"background.js"
],
"persistent": true
},
"content_scripts": [
{
"matches": ["*://*/*"],
"js": ["content.js"],
"run_at": "document_start"
}
],
"permissions": [
"contentSettings",
"webRequest",
"webRequestBlocking",
"*://*/*"
]
}
Но проблема в том, что когда я получаю идентификатор вкладки из фона js, содержимое скрипта уже загружено.
Есть ли способ сделать так, чтобы эта переменная могла быть асинхронно распределена между background.js
и content.js
? Или это просто невозможно?
Могу ли я переключить его и background.js
загрузить переменную из content.js
асинхронно?
UPDATE:
Ужасный хак, который работает, это делает это на переднем плане content.js
:
var sleepScript = document.createElement('script');
var sleepCode = `function sleep (ms) {
var start = new Date().getTime();
while (new Date() < start + ms) {}
return 0;
}
sleep(500);`;
sleepScript.textContent = sleepCode;
(document.head || document.documentElement).appendChild(sleepScript);
Это заставит страницу немного подождать, предоставляя время для запроса фона, прежде чем запускать встроенный dom.
Это работает, но это ужасно.