Я получаю сообщение об ошибке «Вкладки не могут быть отредактированы прямо сейчас (пользователь может перетаскивать вкладку)» в событии обновления/активации/фокусировки вкладки в chrome 91

#javascript #google-chrome-extension

Вопрос:

После недавнего обновления Chrome мое расширение начало срабатывать «Непроверенный runtime.lastError: Вкладки нельзя редактировать прямо сейчас (пользователь может перетаскивать вкладку)», когда я пытаюсь использовать API chrome.tabs. Информации по этому вопросу пока немного, но я считаю, что это ошибка браузера. Тем временем мое расширение заставляет вкладки chrome переключаться заметно медленнее, чем раньше. Теперь для изменения вкладки требуется несколько секунд. Поэтому я ищу обходной путь.

Есть идеи, как это исправить?

Комментарии:

1. Это ошибка .

Ответ №1:

Единственное решение, которое я нашел до сих пор, — это поместить мои обработчики в тайм-аут, подобный этому:

 chrome.tabs.onActivated.addListener((activeInfo) => {
        setTimeout(() => {
           // The old listener handler moves here
        }, 100);
    });
 

Но должен же быть лучший способ, верно?

Комментарии:

1. Привет, Сергей, вы нашли лучшее решение. Мне удалось устранить проблему с помощью этого решения. Но я думаю, что это плохая практика.

Ответ №2:

Вы все равно будете получать ошибки, но, по крайней мере, это будет работать

 chrome.tabs.onActivated.addListener(function(activeInfo) {getActivatedTab();});
function getActivatedTab(){
    chrome.tabs.query({'active': true, 'lastFocusedWindow': true}, function (tabs) {
        try{
            if(tabs[0]!=undefined){
            
                console.log(tabs[0].url);   
            }
        }
        catch(err){
            setTimeout(function() {
            getActivatedTab();
            },100);
        }
    })
}
 

Комментарии:

1. это отлично работает, спасибо … отправил мое расширение с этим исправлением 😀

Ответ №3:

создайте отдельную функцию за пределами chrome.tabs.OnActivated.addListener. этот способ работает на меня.

 function insertScript(tab) {
  chrome.tabs.get(tab.tabId, function (info) {
    console.log(info);
   });
}
chrome.tabs.onActivated.addListener(function (tab) {
   setTimeout(function () {
     insertScript(tab);
    }, 500);
});
 

Ответ №4:

Это ошибка в Chrome91, как указал @wOxxOm.

Это исправление рекомендуется, если вы совершаете много звонков, например xchrome.tabs.query

 const ChromeWrapper = {
  chromeTabsQuery: function (params, callback) {
    chrome.tabs.query(params, tabs => {
      if (chrome.runtime.lastError) {
        setTimeout(function () {
          //console.warn("Patch for xchrome.tabs.query (Chrome 91).");
          ChromeWrapper.chromeTabsQuery(params, callback)
        }, 100); // arbitrary delay
      } else {
        callback(tabs)
      }
    })
  }
}
 

А затем просто замените экземпляры

 xchrome.tabs.query(...
 

с:

 ChromeWrapper.chromeTabsQuery(...
 

Ответ №5:

…Хорошо, у меня нет действительно лучшего решения, кроме setTimeout, так как я действительно не вижу, где публикуется сообщение/событие после завершения вкладки, поэтому я также добавляю a setTimeout , чтобы выполнить некоторые «проб и ошибок».

Но я делаю это так, чтобы переопределить оригинал chrome.tabs.get , чтобы у нас был тот же опыт, что и при его использовании, как и ожидалось. (И легко удалить этот фрагмент, когда они, наконец, исправят его когда-нибудь)

Вот мой код, ура

     chrome.tabs.get = function () {
        const orig_get = chrome.tabs.get.bind(chrome.tabs);
        return async function (tabId) {
            return new Promise(
                resolve => {
                    var tryGet = () => {
                        orig_get(tabId)
                        .then(resolve)
                        .catch(() => {
                            // console.log("retry get");
                            setTimeout(() => {
                                tryGet(tabId);
                            }, 50);
                        })
                    };
                    tryGet();
                }
            )
        }
    }();