@mt-kit/utils
Version:
103 lines • 3.25 kB
JavaScript
/**
* 📡 网络信息
*/
export default async function devicePublicIp() {
// 使用多个IP查询服务,提高成功率
// 优先使用官方和稳定的服务
const ipServices = [
"https://api.ipify.org?format=json", // 官方服务,稳定可靠
"https://ipapi.co/json/", // 官方 API,功能丰富
"https://ipinfo.io/json", // 官方服务,数据准确
"https://api.ip.sb/geoip", // 开源项目,稳定
"https://httpbin.org/ip" // 官方测试服务
];
// 总超时时间:15秒(3个服务 × 5秒)
const totalTimeout = 15000;
const startTime = Date.now();
let ipData = null;
let lastError = null;
// 尝试每个服务
const fetchService = async (service) => {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 5000);
try {
const response = await fetch(service, {
method: "GET",
signal: controller.signal
});
clearTimeout(timeoutId);
if (response.ok) {
const data = await response.json();
return data;
}
throw new Error(`HTTP ${response.status}`);
}
catch (error) {
clearTimeout(timeoutId);
throw error;
}
};
// 按顺序尝试每个服务,成功即停止
for (const service of ipServices) {
// 检查总超时时间
if (Date.now() - startTime > totalTimeout) {
lastError = new Error("总超时时间已到");
break;
}
try {
// eslint-disable-next-line no-await-in-loop
ipData = await fetchService(service);
break;
}
catch (error) {
lastError = error;
console.warn(`❌ IP查询失败: ${service}`, error);
continue;
}
}
if (ipData) {
// 根据不同服务的响应格式提取IP
let ip = "";
let location = "";
const { ip: ipFromData, query, ipAddress, origin } = ipData;
if (ipFromData) {
ip = ipFromData;
}
else if (query) {
ip = query;
}
else if (ipAddress) {
ip = ipAddress;
}
else if (origin) {
ip = origin;
}
// 提取位置信息
if (ipData.country) {
location = ipData.country;
if (ipData.region) {
location += `, ${ipData.region}`;
}
if (ipData.city) {
location += `, ${ipData.city}`;
}
}
else if (ipData.country_name) {
location = ipData.country_name;
if (ipData.region) {
location += `, ${ipData.region}`;
}
if (ipData.city) {
location += `, ${ipData.city}`;
}
}
if (ip) {
return location ? `${ip} (${location})` : ip;
}
throw new Error("无法解析IP地址");
}
else {
throw lastError || new Error("所有IP查询服务都失败了");
}
}
//# sourceMappingURL=public-ip.js.map