Расширение Chrome - Ошибка закрытия "вкладки" при вводе script

Я пишу расширение Chrome, которое определяет тип открываемого файла и на основе этого вставляет скрипт на страницу, который делает много других вещей. Вот часть моего кода для background.js, который внедряет скрипт:

chrome.webRequest.onHeadersReceived.addListener(function(details){
        console.log("Here: " + details.url + " Tab ID: " + details.tabId);
        if(toInject(details))
        {   
            console.log("PDF Detected: " + details.url);
            if(some-condition) 
            {
                //some code
            }
            else
            {
                chrome.tabs.executeScript(details.tabId, { file: "contentscript.js", runAt: "document_start"}, function(result){
                    if(chrome.runtime.lastError)
                    {
                        console.log(chrome.runtime.lastError.message + " Tab ID: " + details.tabId);
                    }
                });
            }
            return {
            responseHeaders: [{
              name: 'X-Content-Type-Options', 
              value: 'nosniff'
            }, 
                {
              name: 'X-Frame-Options', 
                /*
                    Deny rendering of the obtained data.
                    Cant use {cancel:true} as we still need the frame to be accessible.
                */
              value: 'deny'
            }]
          };
        }
}, {
    urls: ['*://*/*'],
    types: ['main_frame', 'sub_frame']
}, ['blocking', 'responseHeaders']);

Вот файл манифеста:

{
    "manifest_version": 2,

    "name": "ABCD",
    "description": "ABCD",
    "version": "1.2",

    "icons": {
        "16" :  "images/16.png",
        "32" :  "images/32.png",
        "48" :  "images/48.png",
        "128" :  "images/128.png"
    },

    "background": {
        "scripts": ["chrome.tabs.executeScriptInFrame.js", "background.js"],
        "persistent": true
    },

    "permissions": [
        "webRequest",
        "<all_urls>",
        "webRequestBlocking",
        "tabs",
        "nativeMessaging"
    ],
    "web_accessible_resources": [ "getFrameId", "aux.html", "chrome-extension:/*", "images/*.png", "images/*.gif", "style.css"]
}

Проблема в том, что при внедрении сценария выполняется последняя часть ошибки, которая показывает, что вкладка была закрыта, а сценарий не внедрен. Если я нажимаю клавишу ВВОД в омнибоксе несколько раз, сценарий вводится и все работает нормально. Вот примерный ряд событий:

Sample output on console

Извините за мое наивное редактирование фотографий: P

Есть еще несколько вещей, которые мы можем вывести из этого изображения:

  1. Первое, что загружается во вкладку с идентификатором 86, это что-то, связанное с моей учетной записью Google. Я вышел из системы, а также отключил функцию prerender в Chrome.
  2. При нажатии клавиши ввода несколько раз вкладка закрывалась, ошибка исчезала, но сценарий, поддерживающий соединение chrome.runtime с background.js, отключался.
  3. И, наконец, все работает нормально.

Я бился головой об этом в течение нескольких дней. Никакой другой вопрос о SO не решает эту проблему. И нигде в Интернете.

EDIT:

Еще одна вещь, на которую следует обратить внимание: пример прогона, показанный на рисунке выше, является одним из таких. Есть много разных поведений. Иногда 3 входа не заставят это работать. Иногда только один будет. Что-то не так из-за пользовательских заголовков, которые я отправляю?

ОБНОВЛЕНИЕ № 1

Нужно заметить заголовки, которые я возвращаю в OnHeadersReceived. Это делается для того, чтобы Chrome не отображал документ. Но после этого все данные файла сбрасываются на экран, и я не хочу, чтобы это появилось. Поэтому я думаю, что мне нужно document_start, чтобы я мог скрыть выгруженные данные до того, как мой скрипт содержимого сделает другие вещи, такие как размещение пользовательского интерфейса на странице.

ОБНОВЛЕНИЕ № 2

Заметил еще одну вещь. Если я открываю новую вкладку, а затем вставляю туда URL-адрес, а затем нажимаю клавишу ввода, ниже выводится фоновая страница на консоли.

Sample output number 2

Таким образом, я думаю, что местоположение окна обновляется позже Chrome. Я прав? Есть обходные пути?

Ответ 1

Сообщение об ошибке "The tab was closed" немного вводит в заблуждение, поскольку вкладка явно не закрыта. В источниках Chrome переменная со строкой называется kRendererDestroyed. Так что ошибка в том, что соответствующий рендерер по какой-то причине уничтожается.

Я получаю сообщение об ошибке, если страница, открытая во вкладке, перенаправлена (таким образом, один рендерер уничтожен, другой создан для той же вкладки, но на этот раз другой URL), в этом случае расширение получит обновления вкладок со статусами, такими как:

  • loading url: 'example.com', здесь вкладка уже возвращена для обратных вызовов и т.д., Но получит ошибку, если попытаться внедрить скрипт
  • loading url: "example.com/other_url"
  • title: 'some title'
  • complete

Мне удалось обойтись путем инъекции скрипта только после получения status: 'complete' (но, вероятно, инъекция на title тоже подойдет)

Не пробовал с pdfs, но chrome, вероятно, заменит рендерер для тех, кто тоже похож на редирект. Так что смотрите больше на статусы страниц и перенаправления/замены рендерера. Надеюсь, это поможет кому-нибудь наткнуться на этот вопрос.