背景
最近有涉及要显示ip属地,但我想白嫖,结果就是白嫖的api接口太慢了,要延迟3到4秒左右,很影响体验,而且不一定稳定。
结果突然看到了这个【ip2region】开源项目,离线识别ip属地,精度自己测试了好多个国家和地区的ip,效果还可以,有98%的成功率。
源地址如下,有各种语言的版本:
ip2region原作者开源项目地址https://github.com/lionsoul2014/ip2region
实现
这里因为我的后端用的是node,就用node的代码做示例
第一步 ,引入依赖
npm install ip2region --save
第二步,下载离线包
下载完成后,进行解压,然后把文件放到自己的项目目录下,如下:
第三步,封装工具类
以下代码可直接复制使用,只需要看一下离线包的地址是否需要更改即可。
内置两个函数:
getIpAddress:官方默认的获取ip属地方法格式
setIpAddress:我自己做的属地格式优化处理
// 导入包
const Searcher = require('../ip2region-master/binding/nodejs/index')
// 指定ip2region数据文件路径
const dbPath = '../ip2region-master/data/ip2region.xdb'
/**
* 获取ip对应真实地址
* @param ip ip地址
* @returns {Promise<string>}
*/
async function getIpAddress (ip) {
try {
// 同步读取vectorIndex
const vectorIndex = Searcher.loadVectorIndexFromFile(dbPath)
// 创建searcher对象
const searcher = Searcher.newWithVectorIndex(dbPath, vectorIndex)
// 查询 await 或 promise均可,例子:data: {region: '中国|0|江苏省|苏州市|电信', ioCount: 2, took: 0.402874}
let data = await searcher.search(ip)
// ip属地格式预处理
data = setIpAddress(data.region)
// 返回结果
return JSON.stringify({
code: 200,
data: data
})
} catch (e) {
// 返回错误
return JSON.stringify({
code: 500,
data: e
})
}
}
/**
* ip属地格式预处理
* @param address ip属地原格式
* @returns {{country: string, province: string, city: string, type: string}}
*/
function setIpAddress (address) {
// 返回体
let adrList = {
country: '',
province: '',
city: '',
type: ''
}
// 根据|分割成数组,然后依次赋值
let list = address.split('|')
adrList.country = list[0] !== '0' ? list[0] : ''
adrList.province = list[2] !== '0' ? list[2] : ''
adrList.city = list[3] !== '0' ? list[3] : ''
adrList.type = list[4] !== '0' ? list[4] : ''
// 返回结果,示例:{ country: '中国', province: '江苏省', city: '徐州市', type: '移动' }
return adrList
}
// 测试
let ip = '223.107.4.177'
getIpAddress(ip)
.then(res => {
let data = JSON.parse(res)
console.log(data)
})
测试效果
可以看到结果很快,只用了十几ms,非常舒服,白嫖成功,在这里感谢原开源项目的作者!