chrome扩展 - 获取最后一个url而不是current

时间:2013-11-05 16:19:53

标签: google-chrome-extension

我正在获取最后访问的网址而不是当前网址。 (当我访问site.com,之后访问site2.com时,我得到的网址是'site.com',刷新site2.com后,我得到的是正确的。

基于这里的答案:
Google Chrome Extension get page information
Display current URL in a chrome extension

我想出了这段代码:

的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",
  ]
}

content.js

chrome.extension.sendRequest({method: "getUrl"}, function(response) {
  console.log(response.data);
});

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

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

1 个答案:

答案 0 :(得分:3)

首先: chrome.extension.sendRequest / onRequest 已弃用。请改用 chrome.runtime.sendMessage / onMessage 此外,只要有可能,请在背景页面上使用 event pages 。大多数情况下,将背景页面转换为事件页面几乎没有任何意义,但可以节省资源。

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

  1. 您访问http://www.site1.com
  2. chrome.tabs.query({...}, callback)被执行(注意回调尚未执行)。
  3. 执行
  4. sendResponse({data: currentUrl})(请注意,此时currentUrl未定义)。
  5. chrome.tabs.query的请求完成,并且执行了回调函数,设置currentUrl = "http://www.site1.com"(但仅在为时已晚)。
  6. 您访问http://www.site2.com
  7. chrome.tabs.query({...}, callback)被执行(注意回调尚未执行)。
  8. sendResponse({data: currentUrl})被执行(请注意,此时currentUrl仍然等于步骤4中的http://www.site1.com
  9. chrome.tabs.query的请求完成,并执行回调函数,设置currentUrl = "http://www.site2.com"(仅在为时已晚之后再次)。
  10. 解决方案:
    (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。 E.g:

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

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