且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

在chrome扩展程序中更新当前活动页面的网址时,如何删除弹出的“离开网站"

更新时间:2023-12-01 21:11:04

理想情况下,扩展API需要处理此问题,因此请加星号

Ideally this is something to be handled by the extensions API so please star crbug/1031791. Meanwhile we can use the workarounds listed below.

仅适用于某些站点.

扩展脚本(弹出或后台):

Extension script (popup or background):

function clearUnloadPrompt() {
  return new Promise(resolve => {
    chrome.tabs.executeScript({
      code: `(${() => {
        const script = document.createElement('script');
        script.textContent = 'window.onbeforeunload = null';
        document.documentElement.appendChild(script).remove();
      }})()`,
      runAt: 'document_start',
    }, () => {
      chrome.runtime.lastError;
      resolve();
    });
  });
}

clearUnloadPrompt().then(() => {
  chrome.tabs.update({url: 'https://www.example.org/'});
});

 

完全确定性的方法是在页面执行之前先注册 beforeunload

应该在任何地方都可以工作,但缺点是,它需要扩展程序需要更新URL的所有URL上的内容脚本.如果您已经在manifest.json中为扩展程序的主要功能请求了这些主机权限,这不是问题.

 

Full exterminatus approach is to register beforeunload before the page does

Should work everywhere but the downside is that it requires a content script on all URLs where your extension needs to update the URL. Although not a problem if you already request these host permissions in manifest.json for your extension's main functionality.

manifest.json摘录:

manifest.json excerpt:

"content_scripts": [{
  "matches": ["<all_urls>"],
  "js": ["content.js"],
  "run_at": "document_start"
}],

(不要忘了使用实际需要的URL模式代替< all_urls> )

(don't forget to use the URL patterns that you actually need instead of <all_urls>)

content.js:

content.js:

const pageEventId = chrome.runtime.id + Math.random;

runInPage(suppressor, pageEventId);

chrome.runtime.onMessage.addListener(msg => {
  if (msg === 'suppressBeforeUnload') {
    window.dispatchEvent(new Event(pageEventId));
  }
});

function runInPage(fn, ...args) {
  const script = document.createElement('script');
  script.textContent = `(${fn})(${JSON.stringify(args).slice(1, -1)})`;
  document.documentElement.appendChild(script);
  script.remove();
}

function suppressor(pageEventId) {
  let suppressBeforeUnload;
  window.addEventListener(pageEventId, () => {
    window.onbeforeunload = null;
    suppressBeforeUnload = true;
  });
  window.addEventListener('beforeunload', e => {
    if (suppressBeforeUnload) {
      e.stopImmediatePropagation();
    }
  });
}

扩展脚本(弹出或后台):

extension script (popup or background):

chrome.tabs.sendMessage(tab.id, 'suppressBeforeUnload', () => {
  chrome.runtime.lastError;
  chrome.tabs.update({url: 'https://www.example.org/'});
});