Как разделить уникальный идентификатор вкладки между содержимым и фоновыми сценариями без асинхронной задержки? - PullRequest
0 голосов
/ 05 ноября 2018

Я построил расширение для 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.

Это работает, но это ужасно.

1 Ответ

0 голосов
/ 06 ноября 2018

На этот вопрос уже был дан ответ ранее, хотя трудно сказать, что это та же проблема на первый взгляд.

https://stackoverflow.com/a/45105934

Ответ довольно описательный, поэтому прочитайте его.

Вот изменения скрипта, которые заставляют его работать:

// background.js
function addSeedCookie(details) {
  details.responseHeaders.push({
    name: "Set-Cookie",
    value: `tab_id=${details.tabId}; Max-Age=2`
  });
  return {
    responseHeaders: details.responseHeaders
  };
}

chrome.webRequest.onHeadersReceived.addListener(
  addSeedCookie, {urls: ["<all_urls>"]}, ["blocking", "responseHeaders"]
);

// inject.js
function getCookie(cookie) { // https://stackoverflow.com/a/19971550/934239
  return document.cookie.split(';').reduce(function(prev, c) {
    var arr = c.split('=');
    return (arr[0].trim() === cookie) ? arr[1] : prev;
  }, undefined);
}

var tabId = getCookie("tab_id");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...