├── .gitignore ├── README.md ├── _locales ├── en_US │ └── messages.json └── zh_CN │ └── messages.json ├── manifest.json ├── res ├── css │ └── contents │ │ └── ip.css ├── icon │ └── icon.png └── js │ ├── ajax.js │ ├── background.js │ └── contents │ └── ip.js └── screenshot ├── 1.png ├── 2.png └── logo.png /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TheIP 2 | 3 | Chrome extension which simply adds the IP of the current website you are viewing to the bottom right. 4 | 5 | I created this extension to solve a problem no other IP extension attempted. To quickly show the current websites IP at all times. 6 | 7 | I use that information daily as a web developer and it has solved my problem. No longer do I have to click through an extension to see the IP, it's just there - bottom right. 8 | 9 | # FEATURES 10 | 11 | Simple solution to always show the current websites IP address instead of clicking through an extension 12 | Moves left or right on mouse over, it won't get in your way 13 | IPv6 support 14 | No external server to return IP - your chrome does all the work locally 15 | Clean, attractive and does the job. 16 | 17 | # PRIVACY 18 | 19 | No-one sees the IP but you. There is no reliance on an external server to return the IP. Chrome returns the IP address itself on the users side. This takes into consideration local DNS and Host changes. 20 | 21 | 22 | # MORE 23 | 24 | More available here: [https://chrome.google.com/webstore/detail/the-ip/ehaiielehjkjaofolpmdmcjgffbeicck](https://chrome.google.com/webstore/detail/the-ip/ehaiielehjkjaofolpmdmcjgffbeicck) 25 | -------------------------------------------------------------------------------- /_locales/en_US/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "extDesp": { 3 | "message": "A very Simple Chrome plugin, show the IP address at the bottom of the website, Low memory usage, IPv4 & IPv6 supported." 4 | }, 5 | "extName": { 6 | "message": "The IP" 7 | } 8 | } -------------------------------------------------------------------------------- /_locales/zh_CN/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "extDesp": { 3 | "message": "一个非常简单的Chrome插件,能够在网页中右下角显示它的IP地址(支持IPv4和IPv6),并且点击图标关闭插件,保证最低资源占用。" 4 | }, 5 | "extName": { 6 | "message": "The IP" 7 | } 8 | } -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "background": { 3 | "scripts": [ "/res/js/ajax.js", "/res/js/background.js" ] 4 | }, 5 | "content_scripts": [ { 6 | "all_frames": false, 7 | "css": [ "/res/css/contents/ip.css" ], 8 | "js": [ "/res/js/contents/ip.js" ], 9 | "matches": [ "http://*/*", "https://*/*" ], 10 | "run_at": "document_end" 11 | } ], 12 | "default_locale": "zh_CN", 13 | "description": "__MSG_extDesp__", 14 | "name": "__MSG_extName__", 15 | "icons": { 16 | "128": "/res/icon/icon.png", 17 | "64": "/res/icon/icon.png", 18 | "32": "/res/icon/icon.png", 19 | "16": "/res/icon/icon.png" 20 | }, 21 | "manifest_version": 2, 22 | "browser_action": { 23 | "default_icon": { 24 | "19": "res/icon/icon.png", 25 | "38": "res/icon/icon.png" 26 | } 27 | }, 28 | "permissions": [ "tabs", "http://*/*", "https://*/*", "webRequest", "storage" ], 29 | "version": "1.1.0" 30 | } 31 | -------------------------------------------------------------------------------- /res/css/contents/ip.css: -------------------------------------------------------------------------------- 1 | div#chrome_the_website_ip { 2 | display:block!important; 3 | position: fixed!important; 4 | bottom: 3px!important; 5 | background: #d9ead3!important; 6 | padding: 4px 5px!important; 7 | border: 1px solid #919191!important; 8 | font: 12px/1.1 'Microsoft YaHei', 'Arial', Helvetica, sans-serif!important; 9 | color: #333!important; 10 | cursor: default!important; 11 | outline: 0!important; 12 | vertical-align: baseline!important; 13 | margin: 0!important; 14 | -webkit-touch-callout: none!important; 15 | -webkit-user-select: none!important; 16 | user-select: none!important; 17 | z-index: 2147483646!important; 18 | opacity: 1!important; 19 | } 20 | 21 | div.chrome_the_website_ip_right { 22 | right: 10px!important; 23 | } 24 | 25 | div.chrome_the_website_ip_left { 26 | left: 10px!important; 27 | } 28 | 29 | /* hide if in print view */ 30 | @media print { 31 | div#chrome_the_website_ip {display:none!important;} 32 | } -------------------------------------------------------------------------------- /res/icon/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hustcc/TheIP/3ab398f057676b0b0ffdf220a29d1ad78f09a9e5/res/icon/icon.png -------------------------------------------------------------------------------- /res/js/ajax.js: -------------------------------------------------------------------------------- 1 | function http_ajax(link, method, aysnc, callback){ 2 | //创建XMLHttpRequest对象,用原生的AJAX方式读取内容 3 | var xhr = new XMLHttpRequest(); 4 | //处理细节 5 | xhr.onreadystatechange = function() { 6 | //后端已经处理完成,并已将请求response回来了 7 | if (xhr.readyState === 4) { 8 | var respData; 9 | 10 | //判断status是否为OK 11 | if (xhr.status === 200 && xhr.responseText) { 12 | //OK时回送给客户端的内容 13 | respData = { 14 | success : true, //成功 15 | content : xhr.responseText //文件内容 16 | }; 17 | } else { //失败 18 | respData = { 19 | success : false, //失败 20 | content : "load remote file content failed." //失败信息 21 | }; 22 | } 23 | //触发回调,并将结果回送 24 | callback(respData); 25 | } 26 | }; 27 | 28 | //打开读通道 29 | xhr.open(method, link, aysnc); 30 | 31 | //设置HTTP-HEADER 32 | // xhr.setRequestHeader("Content-Type","text/plain;charset=UTF-8"); 33 | // xhr.setRequestHeader("Access-Control-Allow-Origin","*"); 34 | 35 | //开始进行数据读取 36 | xhr.send(); 37 | }; 38 | -------------------------------------------------------------------------------- /res/js/background.js: -------------------------------------------------------------------------------- 1 | var setting = {'status': 'on'}; 2 | 3 | 4 | function saveSetting() { 5 | chrome.storage.local.set({'status': setting['status']}, function() {}); // 保存到本地 6 | } 7 | 8 | 9 | function setStatus(status) { 10 | if (status !== 'off') { 11 | chrome.browserAction.setBadgeText({'text': 'on'}); 12 | chrome.browserAction.setBadgeBackgroundColor({'color': '#14892c'}); 13 | 14 | // 开始监听 15 | currentIPList = {}; 16 | chrome.webRequest.onCompleted.addListener(onCompletedFunc , { urls: [], types: ['main_frame'] }, []); 17 | } 18 | else { 19 | chrome.browserAction.setBadgeText({'text': 'off'}); 20 | chrome.browserAction.setBadgeBackgroundColor({'color': '#d04437'}); 21 | 22 | // 清楚监听 23 | currentIPList = {}; 24 | chrome.webRequest.onCompleted.removeListener(onCompletedFunc); 25 | } 26 | saveSetting(); 27 | } 28 | 29 | function toggleOnOff(tab) { 30 | if (setting['status'] === 'on') { 31 | setting['status'] = 'off'; 32 | 33 | } 34 | else { 35 | setting['status'] = 'on'; 36 | } 37 | setStatus(setting['status']); 38 | } 39 | 40 | function ipLocation(data) { 41 | var l = []; 42 | if (data.country !== 'XX') { 43 | l.push(data.country); 44 | } 45 | if (data.region !== 'XX') { 46 | l.push(data.region); 47 | } 48 | if (data.city !== 'XX') { 49 | l.push(data.city); 50 | } 51 | if (data.isp !== 'XX') { 52 | l.push(data.isp); 53 | } 54 | return l.join(' '); 55 | } 56 | 57 | // 监听点击事件 58 | chrome.browserAction.onClicked.addListener(toggleOnOff); 59 | 60 | // 回复状态 61 | chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) { 62 | // 请求设置状态 63 | if ('status' === request.get) { 64 | sendResponse(setting); 65 | } 66 | else if ('ip' === request.get) { 67 | var ip = 'null'; 68 | if (currentIPList[sender.tab.url]) { 69 | ip = currentIPList[sender.tab.url]; 70 | delete currentIPList[sender.tab.url]; 71 | } 72 | sendResponse({'ip': ip}); 73 | } 74 | else if ('location' === request.get) { 75 | var location = ''; 76 | http_ajax('http://ip.taobao.com/service/getIpInfo.php?ip=' + request.data, 'GET', false, function(data) { 77 | if (true === data.success) { 78 | try { 79 | var loc = JSON.parse(data.content); 80 | if (loc.code === 0) { 81 | location = ipLocation(loc.data || {}); 82 | } else { 83 | location = '内网或未分配 IP'; 84 | } 85 | } catch(exception) { 86 | location = '无法识别的 IP'; 87 | } 88 | } 89 | else { 90 | location = ''; 91 | } 92 | }); 93 | sendResponse({'location': location}); 94 | } 95 | }); 96 | 97 | // 缓存IP,每次用完就清空 98 | var currentIPList = {}; 99 | 100 | function onCompletedFunc(info) { 101 | currentIPList[ info.url ] = info.ip; 102 | return; 103 | } 104 | 105 | // 加载配置 106 | chrome.storage.local.get(['status'], function(data) { 107 | if ('off' === data['status']) { 108 | setting['status'] = 'off'; 109 | } 110 | // 读取配置成功之后,显示图标 111 | setStatus(setting['status']); 112 | }); 113 | -------------------------------------------------------------------------------- /res/js/contents/ip.js: -------------------------------------------------------------------------------- 1 | var ipDom = null; 2 | 3 | function tag(type, id, className, innerHTML) { 4 | var el = document.createElement(type); 5 | el.id = id; 6 | el.className = className; 7 | el.innerHTML = innerHTML; 8 | return el; 9 | } 10 | 11 | function requestIPLocation(ip) { 12 | chrome.extension.sendMessage({'get': 'location', 'data': ip}, function(response) { 13 | if (response && response.location && ipDom) { 14 | ipDom.innerHTML = ipDom.innerHTML + '
' + response.location; 15 | } 16 | }); 17 | } 18 | 19 | chrome.extension.sendMessage({'get': 'status'}, function(response) { 20 | if ('off' !== response.status) { 21 | // 开启状态 22 | chrome.extension.sendMessage({'get': 'ip'}, function(response) { 23 | var ip = 'null'; 24 | if (response && response.ip) { 25 | ip = response.ip; 26 | } 27 | ipDom = tag('div', 'chrome_the_website_ip', 'chrome_the_website_ip_right', ip); 28 | document.body.appendChild(ipDom); 29 | ipDom.onmouseover = function() { 30 | 31 | if (ipDom.className === 'chrome_the_website_ip_right') { 32 | ipDom.className = 'chrome_the_website_ip_left'; 33 | } 34 | else { 35 | ipDom.className = 'chrome_the_website_ip_right'; 36 | } 37 | }; 38 | // 完成之后,请求归属地数据 39 | if (ip && (ip != 'null')) 40 | requestIPLocation(ip); 41 | }); 42 | } 43 | }); 44 | -------------------------------------------------------------------------------- /screenshot/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hustcc/TheIP/3ab398f057676b0b0ffdf220a29d1ad78f09a9e5/screenshot/1.png -------------------------------------------------------------------------------- /screenshot/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hustcc/TheIP/3ab398f057676b0b0ffdf220a29d1ad78f09a9e5/screenshot/2.png -------------------------------------------------------------------------------- /screenshot/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hustcc/TheIP/3ab398f057676b0b0ffdf220a29d1ad78f09a9e5/screenshot/logo.png --------------------------------------------------------------------------------