理想情况下,这是由扩展 API 处理的,因此请加注星标crbug/1031791。同时我们可以使用下面列出的解决方法。
简单的做法是清除window.onbeforeunload
仅适用于某些网站。
扩展脚本(弹出或背景):
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 中为您的扩展程序的主要功能请求这些主机权限,这不是问题。
manifest.json 摘录:
"content_scripts": [{
"matches": ["<all_urls>"],
"js": ["content.js"],
"run_at": "document_start"
}],
(不要忘记使用您实际需要的 URL 模式,而不是 <all_urls>)
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();
}
});
}
扩展脚本(弹出或背景):
chrome.tabs.sendMessage(tab.id, 'suppressBeforeUnload', () => {
chrome.runtime.lastError;
chrome.tabs.update({url: 'https://www.example.org/'});
});