XMLHttpRequest中“Unchecked runtime.lastError:消息端口在收到响应之前关闭了”错误的解决方法
2024-04-25 21:22:09
如何解决XMLHttpRequest中“Unchecked runtime.lastError:消息端口在收到响应之前关闭了”的错误
问题
在使用XMLHttpRequest从后台脚本注入内容脚本时,可能会遇到以下错误:
Unchecked runtime.lastError: The message port closed before a response was received.
解决方法
1. 检查Chrome扩展程序API版本
使用过时的API版本可能会导致消息传递问题。请确保已更新到最新的版本。
2. 确认内容脚本已注入
使用 console.log() 在内容脚本中输出消息,以验证其是否已运行。
3. 使用chrome.runtime.onMessage.addListener
在内容脚本中,使用 chrome.runtime.onMessage.addListener() 侦听来自后台脚本的消息。
4. 正确处理消息
在后台脚本中,使用 chrome.runtime.sendMessage() 发送消息,确保消息数据已正确序列化。
5. 检查消息端口
使用 chrome.tabs.connect() 建立消息端口,验证端口是否已正确创建。
6. 检查URL模式
在后台脚本中,使用 if (/http:/.test(e.url) || /https:/.test(e.url)) 检查URL模式,确保模式正确。
7. 使用异步函数
将消息传递代码包装在异步函数中,例如使用 async/await 或 Promise。
8. 启用调试日志
在 Chrome 开发者工具中启用调试日志,提供错误的更多详细信息。
示例代码
background.js:
chrome.browserAction.onClicked.addListener(async function (event) {
// ...
const xhr = new XMLHttpRequest();
xhr.open("GET", "https://example.com/script.js", true);
xhr.onreadystatechange = async function () {
if (xhr.readyState == 4) {
const tabs = await chrome.tabs.query({ currentWindow: true });
tabs.forEach(async (e) => {
if (/http:/.test(e.url) || /https:/.test(e.url)) {
await chrome.tabs.executeScript(e.tabId, { code: xhr.responseText });
const port = chrome.tabs.connect(e.tabId);
connect(port, show_floater);
console.log(e.url);
}
});
}
}
xhr.send();
});
content.js:
chrome.runtime.onMessage.addListener(async function (request, sender, sendResponse) {
// ...
if (request.text == "am I connected?") {
// ...
}
});
常见问题解答
1. 返回 true 是否能解决此错误?
否,返回 true 不会解决消息端口错误,反而会掩盖潜在问题。
2. 如何知道内容脚本是否已注入?
在内容脚本中使用 console.log() 输出消息,并检查控制台是否有输出。
3. 如何正确使用chrome.runtime.sendMessage()?
chrome.runtime.sendMessage(extensionId, request, options, callback)
4. 如何检查消息端口是否已正确创建?
chrome.runtime.onConnect.addListener(function(port) {
// ...
});
5. 为什么需要使用异步函数?
异步函数可确保在收到响应之前不会执行后续代码。