最近想通过获取用户ip信息来准确的输出欢迎界面,在网上搜了半天接口,就没几个能用的,后来偶然发现了lionsoul2014/ip2region这个开源库,提供了很多语言的绑定,速度也是很快的,通过它所提供的xdb数据库来进行本地查询,快速方便,当然也支持自定义数据库
如何使用
我只用过它NodeJS和Go的绑定, 接口调用简单,其中NodeJS已经整合了数据库到npm里,Go版本你需要自行下载作者提供的数据库,放到项目中进行读取,所以这里以Go为例进行演示
首先下载data目录下的ip2region.xdb
数据库文件,然后 go get github.com/lionsoul2014/ip2region/binding/golang
获取Go绑定,把数据库文件放到项目中任意位置
import (
"github.com/lionsoul2014/ip2region/binding/golang/xdb"
"strings"
"toolkit-api/utils/cache"
)
type IpInfo struct {
IpAddr string `json:"ip_addr"`
Country string `json:"country"`
Region string `json:"region"`
Province string `json:"province"`
City string `json:"city"`
ISP string `json:"isp"`
}
var cacheId = "IPInfo_db_VIndex"
func getCacheVIndex() []byte {
return cache.Get(cacheId)
}
func setCacheVIndex(data []byte) {
cache.Set(cacheId, data)
}
func GetIpInfo(ip string) (IpInfo, error) {
var (
result IpInfo
err error
dPath = "./assets/ipinfo_db/ip2region.xdb"
)
// 这里对VectorIndex进行了缓存,目的是减小一次IO操作
vIndex := getCacheVIndex()
if vIndex == nil {
vIndex, err = xdb.LoadVectorIndexFromFile(dPath)
if err != nil {
return result, err
}
setCacheVIndex(vIndex)
}
searcher, err := xdb.NewWithVectorIndex(dPath, vIndex)
if err != nil {
return result, err
}
defer searcher.Close()
region, err := searcher.SearchByStr(ip)
if err != nil {
return result, err
}
// 原始数据只是字符串,我们进行处理提取信息
regionData := strings.Split(region, "|")
result.IpAddr = ip
result.Country = notZero(regionData[0])
result.Region = notZero(regionData[1])
result.Province = notZero(regionData[2])
result.City = notZero(regionData[3])
result.ISP = notZero(regionData[4])
return result, nil
}
func notZero(s string) string {
if s == "0" {
return ""
}
return s
}
总结
得益于该库所使用的索引算法,查询性能很出色,所提供的数据库在国内的准确性也很不错,我的ip在很多网站显示的是其他省的,但该库提供的数据库就是正确的地理位置,大家在搭建自己的api toolkit时,不妨试试这个库来实现ip信息获取的功能