chaos-zhu bcfbe0d6b3
2022-12-12 20:35:52 +08:00

144 lines
5.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const axios = require('axios')
const request = axios.create({ timeout: 3000 })
// 为空时请求本地IP
const getNetIPInfo = async (searchIp = '') => {
searchIp = searchIp.replace(/::ffff:/g, '') || '' // fix: nginx反代
if(['::ffff:', '::1'].includes(searchIp)) searchIp = '127.0.0.1'
try {
let date = Date.now()
let ipUrls = [
// 45次/分钟&支持中文(无限制)
`http://ip-api.com/json/${ searchIp }?lang=zh-CN`,
// 10000次/月&支持中文(依赖IP计算调用次数)
`http://ipwho.is/${ searchIp }?lang=zh-CN`,
// 1500次/天(依赖密钥, 超出自行注册)
`https://api.ipdata.co/${ searchIp }?api-key=c6d4d04d5f11f2cd0839ee03c47c58621d74e361c945b5c1b4f668f3`,
// 50000/月(依赖密钥, 超出自行注册)
`https://ipinfo.io/${ searchIp }/json?token=41c48b54f6d78f`,
// 1000次/天(依赖密钥, 超出自行注册)
`https://api.ipgeolocation.io/ipgeo?apiKey=105fc2c7e8864ec08b98e1ad4e8cbc6d&ip=${ searchIp }`,
// 1000次/天(依赖IP计算调用次数)
`https://ipapi.co${ searchIp ? `/${ searchIp }` : '' }/json`,
// 国内IP138提供(无限制)
`https://sp1.baidu.com/8aQDcjqpAAV3otqbppnN2DJv/api.php?query=${ searchIp }&resource_id=5809`
]
let result = await Promise.allSettled(ipUrls.map(url => request.get(url)))
let [ipApi, ipwho, ipdata, ipinfo, ipgeolocation, ipApi01, ip138] = result
let searchResult = []
if(ipApi.status === 'fulfilled') {
let { query: ip, country, regionName, city } = ipApi.value?.data || {}
searchResult.push({ ip, country, city: `${ regionName } ${ city }`, date })
}
if(ipwho.status === 'fulfilled') {
let { ip, country, region: regionName, city } = ipwho.value?.data || {}
searchResult.push({ ip, country, city: `${ regionName } ${ city }`, date })
}
if(ipdata.status === 'fulfilled') {
let { ip, country_name: country, region: regionName, city } = ipdata.value?.data || {}
searchResult.push({ ip, country, city: `${ regionName } ${ city }`, date })
}
if(ipinfo.status === 'fulfilled') {
let { ip, country, region: regionName, city } = ipinfo.value?.data || {}
searchResult.push({ ip, country, city: `${ regionName } ${ city }`, date })
}
if(ipgeolocation.status === 'fulfilled') {
let { ip, country_name: country, state_prov: regionName, city } = ipgeolocation.value?.data || {}
searchResult.push({ ip, country, city: `${ regionName } ${ city }`, date })
}
if(ipApi01.status === 'fulfilled') {
let { ip, country_name: country, region: regionName, city } = ipApi01.value?.data || {}
searchResult.push({ ip, country, city: `${ regionName } ${ city }`, date })
}
if(ip138.status === 'fulfilled') {
let [res] = ip138.value?.data?.data || []
let { origip: ip, location: country, city = '', regionName = '' } = res || {}
searchResult.push({ ip, country, city: `${ regionName } ${ city }`, date })
}
// console.log(searchResult)
let validInfo = searchResult.find(item => Boolean(item.country))
consola.info('查询IP信息', validInfo)
return validInfo || { ip: '获取IP信息API出错,请排查或更新API', country: '未知', city: '未知', date }
} catch (error) {
consola.error('getIpInfo Error: ', error)
return {
ip: '未知',
country: '未知',
city: '未知',
error
}
}
}
const throwError = ({ status = 500, msg = 'defalut error' } = {}) => {
const err = new Error(msg)
err.status = status // 主动抛错
throw err
}
const isIP = (ip = '') => {
const isIPv4 = /^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$/
const isIPv6 = /^([\da-fA-F]{1,4}:){7}[\da-fA-F]{1,4}|:((:[\dafAF]1,4)1,6|:)|:((:[\dafAF]1,4)1,6|:)|^[\da-fA-F]{1,4}:((:[\da-fA-F]{1,4}){1,5}|:)|([\dafAF]1,4:)2((:[\dafAF]1,4)1,4|:)|([\dafAF]1,4:)2((:[\dafAF]1,4)1,4|:)|^([\da-fA-F]{1,4}:){3}((:[\da-fA-F]{1,4}){1,3}|:)|([\dafAF]1,4:)4((:[\dafAF]1,4)1,2|:)|([\dafAF]1,4:)4((:[\dafAF]1,4)1,2|:)|^([\da-fA-F]{1,4}:){5}:([\da-fA-F]{1,4})?|([\dafAF]1,4:)6:|([\dafAF]1,4:)6:/
return isIPv4.test(ip) || isIPv6.test(ip)
}
const randomStr = (len) =>{
len = len || 16
let str = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678',
a = str.length,
res = ''
for (let i = 0; i < len; i++) res += str.charAt(Math.floor(Math.random() * a))
return res
}
// 获取UTC-x时间
const getUTCDate = (num = 8) => {
let date = new Date()
let now_utc = Date.UTC(date.getUTCFullYear(), date.getUTCMonth(),
date.getUTCDate(), date.getUTCHours() + num,
date.getUTCMinutes(), date.getUTCSeconds())
return new Date(now_utc)
}
const formatTimestamp = (timestamp = Date.now(), format = 'time') => {
if(typeof(timestamp) !== 'number') return '--'
let date = new Date(timestamp)
let padZero = (num) => String(num).padStart(2, '0')
let year = date.getFullYear()
let mounth = padZero(date.getMonth() + 1)
let day = padZero(date.getDate())
let hours = padZero(date.getHours())
let minute = padZero(date.getMinutes())
let second = padZero(date.getSeconds())
let weekday = ['周日', '周一', '周二', '周三', '周四', '周五', '周六' ]
let week = weekday[date.getDay()]
switch (format) {
case 'date':
return `${ year }-${ mounth }-${ day }`
case 'week':
return `${ year }-${ mounth }-${ day } ${ week }`
case 'hour':
return `${ year }-${ mounth }-${ day } ${ hours }`
case 'time':
return `${ year }-${ mounth }-${ day } ${ hours }:${ minute }:${ second }`
default:
return `${ year }-${ mounth }-${ day } ${ hours }:${ minute }:${ second }`
}
}
module.exports = {
getNetIPInfo,
throwError,
isIP,
randomStr,
getUTCDate,
formatTimestamp
}