0

我得到的是最后访问的 url 而不是当前的。(当我访问 site.com 并随后访问 site2.com 时,我得到的网址是“site.com”,在我刷新 site2.com 后,我得到了正确的网址。

基于此处的答案:
Google Chrome 扩展程序获取页面信息
在 chrome 扩展程序中显示当前 URL

我想出了这段代码:

清单.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.
});

我还尝试将此代码直接放在 content.js 下面,但在 background.js 中出现错误,并且 url 设置为chrome://extensions/.

chrome.tabs.query({ currentWindow: true, active: true }, function (tabs) {
  currentUrl = tabs[0].url;
});

这样做的正确方法是什么?

4

1 回答 1

4

首先: chrome.extension.sendRequest/onRequest已弃用。请改用chrome.runtime.sendMessage / onMessage
此外,尽可能选择事件页面而不是背景页面。大多数情况下,将背景页面转换为事件页面几乎不需要任何时间,但可以节省大量资源。

问题:
chrome.tabs.query是异步的。这意味着,当被调用时,它会初始化请求,然后完成其执行,以便执行脚本的下一部分。一旦请求完成,注册的回调函数就会被执行。因此,这就是您的情况:

  1. 你访问http://www.site1.com
  2. chrome.tabs.query({...}, callback)被执行(注意回调尚未执行)。
  3. sendResponse({data: currentUrl})被执行(注意此时currentUrl未定义)。
  4. chrome.tabs.query的请求完成并执行回调函数,设置currentUrl = "http://www.site1.com"(但只有在为时已晚)。
  5. 你访问http://www.site2.com
  6. chrome.tabs.query({...}, callback)被执行(注意回调尚未执行)。
  7. sendResponse({data: currentUrl})被执行(请注意,此时currentUrl仍然等于http://www.site1.com从步骤 4 开始)。
  8. chrome.tabs.query的请求完成并执行回调函数,设置currentUrl = "http://www.site2.com"(再次只是在为时已晚之后)。

解决方案:
(A)
移动回调内部的逻辑。
注意:每当异步调用回调(即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 !!!
    }
});

(B)
在您的情况下更简单,onMessage侦听器的sender参数包含包含 URL 信息的字段。例如:tab

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
    if(request.method && (request.method == "getURL") && sendResponse) {
        sendResponse({ data: sender.tab.url });
    }
});

(C)
如果您只需要内容脚本上下文中的 URL,为什么不在location.href内容脚本中使用?

于 2013-11-06T11:26:26.587 回答