我得到的是上次访问的网址,而不是当前的网址。(当我转到 site.com 然后转到 site2.com 时,我得到的URL是"site.com",刷新 site2.com 后,我得到了正确的网址。
基于这里的答案:
谷歌浏览器扩展程序获取页面信息
在镶边扩展程序中
显示当前网址
我想出了这个代码:
manifest.json
{
"manifest_version": 2,
"browser_action": {
"default_popup": "action.html"
},
"content_scripts": [
{
"matches": ["http://*/*", "https://*/*"],
"js": ["content.js"],
"run_at": "document_end"
}
],
"background": {
"scripts": ["background.js"]
},
"permissions": [
"tabs",
"unlimitedStorage",
]
}
内容.js
chrome.extension.sendRequest({method: "getUrl"}, function(response) {
console.log(response.data);
});
背景.js
chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
if(request.method == "getUrl") {
chrome.tabs.query({ currentWindow: true, active: true }, function (tabs) {
currentUrl = tabs[0].url;
});
sendResponse({data: currentUrl});
}
else
sendResponse({}); // snub them.
});
我还尝试将此代码直接放在内容中.js并且我收到错误并在后台.js并且 url 设置为 chrome://extensions/
.
chrome.tabs.query({ currentWindow: true, active: true }, function (tabs) {
currentUrl = tabs[0].url;
});
正确的方法是什么?
首先:chrome.extension.sendRequest/onRequest 已弃用。请改用chrome.runtime.sendMessage/onMessage。
此外,只要有可能,请优先选择事件页面而不是背景页面。大多数情况下,将背景页面转换为事件页面几乎不需要,但可以节省大量资源。
问题:
chrome.tabs.query 是异步的。这意味着,在调用时,它会初始化请求,然后完成其执行,以便执行脚本的下一部分。请求完成后,将执行已注册的回调函数。因此,这就是您的情况下发生的情况:
- 您访问
http://www.site1.com
. -
chrome.tabs.query({...}, callback)
被执行(请注意,回调尚未执行)。 -
sendResponse({data: currentUrl})
被执行(请注意,此时尚未定义currentUrl
)。 -
chrome.tabs.query
的请求完成并执行回调函数,设置currentUrl = "http://www.site1.com"
(但仅在为时已晚之后)。 - 您访问
http://www.site2.com
. -
chrome.tabs.query({...}, callback)
被执行(请注意,回调尚未执行)。 -
sendResponse({data: currentUrl})
被执行(请注意,此时currentUrl
仍然等于步骤 4 中的http://www.site1.com
)。 -
chrome.tabs.query
的请求完成并执行回调函数,设置currentUrl = "http://www.site2.com"
(再次设置为时已晚)。
解决方案:
(一)
在回调内移动逻辑。
(注意:每当回调(即 sendResponse
) 将被异步调用,onMessage
侦听器必须返回 true
.)
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
if(request.method && (request.method == "getURL")) {
if (sendResponse) {
chrome.tabs.query({
currentWindow: true,
active: true
}, function(tabs) {
if (tabs.length > 0) {
sendResponse({ data: tabs[0].url });
}
});
/* Since 'sendResponse' is to going be called
* asynchronously, it is necessary to return 'true' */
return true;
}
} else {
// Do not talk to strangers !!!
}
});
(二)
在您的情况下更简单的是,onMessage 侦听器的 sender
参数包含包含 URL 信息的字段tab
。例如:
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
if(request.method && (request.method == "getURL") && sendResponse) {
sendResponse({ data: sender.tab.url });
}
});
(三)
如果您只需要内容脚本上下文中的 URL,为什么不使用内容脚本中的 location.href
?