将主机解析为IP地址,并使用Chrome扩展程序在弹出窗口中显示该地址

时间:2012-07-14 15:20:36

标签: javascript google-chrome google-chrome-extension dns ip-address

我正在开发Chrome扩展程序以执行以下操作。

单击图标时,弹出窗口显示当前显示页面的IP地址。

此扩展程序应适用于每个页面。但问题是当加载url时应该加载当前url的IP。不是在显示弹出窗口时,弹出窗口和通过Web服务获取IP地址之间不会有延迟。

因此,实质上,每个标签的扩展弹出窗口都是不同的。

这应该是页面操作还是浏览器操作?

如何在后台从Web服务获取数据并在实际显示之前将其分配给弹出窗口?

任何信息都非常适合。

1 个答案:

答案 0 :(得分:4)

此答案包含测试扩展程序的完整代码。要进行测试,请创建每个文件,将其存储在同一目录中,然后通过chrome://extensions/加载它(开发人员模式)。


“此扩展程序应该适用于每个页面。” - > 浏览器操作

有两种方法可以尽快捕获网页的网址。这两种方法都必须在后台页面中使用。

  1. 使用chrome.tabs.onUpdated

    chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
        if (changeInfo.status === 'loading' && changeInfo.url) {
            processUrl(tabId, tab.url); // or changeInfo.url, does not matter
        }
    });
    
  2. 使用chrome.webRequest API:

    chrome.webRequest.onBeforeRequest.addListener(function(details) {
        processUrl(details.tabId, details.url); // Defined below
    }, {
        urls: ["*://*/*"],
        types: ["main_frame"]
    });
    
  3. 任何一种方法都会捕获制表符和网址。在您的情况下 - 在当前选项卡的弹出窗口中显示IP - ,首选方法,因为它是为每个选项卡更新触发的。后者只会针对http:https:网址触发。

    任一方法都调用processUrl函数。此函数将处理给定选项卡的URL。我建议缓存IP地址,以避免对Web服务的请求过多。

    background.js

    var tabToHost = {};
    var hostToIP = {};
    
    function processUrl(tabId, url) {
        // Get the host part of the URL. 
        var host = /^(?:ht|f)tps?:\/\/([^/]+)/.exec(url);
    
        // Map tabId to host
        tabToHost[tabId] = host ? host=host[1] : '';
    
        if (host && !hostToIP[host]) { // Known host, unknown IP
            hostToIP[host] = 'N/A';    // Set N/A, to prevent multiple requests
            // Get IP from a host-to-IP web service
            var x = new XMLHttpRequest();
            x.open('GET', 'http://www.fileformat.info/tool/rest/dns.json?q=' + host);
            x.onload = function() {
                var result = JSON.parse(x.responseText);
                if (result && result.answer && result.answer.values && result.answer.values[0]) {
                    // Lookup successful, save address
                    hostToIP[host] = result.answer.values[0].address;
                    setPopupInfo(tabId);
                 }
             };
             x.send();
        }
    
        // Set popup info, with currently (un)known information
        setPopupInfo(tabId);
    }
    function setPopupInfo(tabId) { // Notify all popups
        chrome.extension.getViews({type:'popup'}).forEach(function(global) {
            global.notify(tabId);
        });
    }
    
    // Remove entry from tabToIp when the tab is closed.
    chrome.tabs.onRemoved.addListener(function(tabId) {
        delete tabToHost[tabId];
    });
    // Add entries: Using method 1 ( `onUpdated` )
    chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
        if (changeInfo.status === 'loading' && changeInfo.url) {
            processUrl(tabId, tab.url); // or changeInfo.url, does not matter
        }
    });
    
    // Init: Get all windows and tabs, to fetch info for current hosts
    chrome.windows.getAll({populate: true}, function(windows) {
        windows.forEach(function(win) {
            if (win.type == 'normal' && win.tabs) {
                for (var i=0; i<win.tabs.length; i++) {
                    processUrl(win.tabs[i].id, win.tabs[i].url);
                }
            }
        });
    });
    

    找到IP后,IP将保存在哈希中。这个哈希看起来像:

    hostToIP = {
        'stackoverflow.com': '64.34.119.12',
        'superuser.com': '64.34.119.12'
    };
    

    如您所见,两台主机可能引用相同的IP。反之亦然:主机可能有多个IP地址(例如Lookup Google)。 如果打开,后台页面将与浏览器操作弹出窗口进行通信。

    popup.js

    // Get initial tab and window ID
    var tabId, windowId;
    chrome.tabs.query({active:true, currentWindow:true, windowType:'normal'},
      function(tabs) {
        if (tabs[0]) {
            // Found current tab
            window.tabId = tabs[0].id;
            windowId = tabs[0].windowId;
            requestUpdate();
        }
    });
    // Receive tab ID updates
    chrome.tabs.onActivated.addListener(function(activeInfo) {
        if (activeInfo.windowId === windowId) {
            requestUpdate();
        }
    });
    
    // Communication with background:
    var background = chrome.extension.getBackgroundPage();
    
    // Backgrounds calls notify()
    function notify(tabId, url, ip) {
        if (tabId === window.tabId) { // Tab == current active tab
            requestUpdate();
        }
    }
    // Get fresh information from background
    function requestUpdate() {
        // tabId is the current active tab in this window
        var host = background.tabToHost[tabId] || '';
        var ip = host && background.hostToIP[host] || 'N/A';
        // Now, do something. For example:
        document.getElementById('host').textContent = host;
        document.getElementById('ip').textContent = ip;
    }
    

    popup.html

    <!DOCTYPE html>
    <html>
    <meta charset="utf-8">
    <title>Host to IP</title>
    <script src="popup.js"></script>
    </head>
    <body style="white-space:pre;font-family:monospace;">
    Host: <span id="host"></span>
    IP  : <span id="ip"></span>
    </body>
    </html>
    

    manifest.json

    {
        "name": "Host To Tab",
        "manifest_version": 2,
        "version": "1.0",
        "description": "Shows the IP of the current tab at the browser action popup",
        "background": {"scripts":["background.js"]},
        "permissions": ["http://www.fileformat.info/tool/rest/dns.json?q=*", "tabs"],
        "browser_action": {
            "default_popup": "popup.html"
        }
    }
    

    相关文件