移除服务器代码中对于客户端IP地址数据的获取

This commit is contained in:
Alex Yang
2026-01-02 22:40:46 +08:00
parent 8889c875a9
commit dc2deb98b8
2 changed files with 154 additions and 295 deletions

View File

@@ -14,6 +14,103 @@ let currentSortDirection = 'desc'; // 默认降序
let ipGeolocationCache = {};
const GEOLOCATION_CACHE_EXPIRY = 24 * 60 * 60 * 1000; // 缓存有效期24小时
// 获取IP地理位置信息
async function getIpGeolocation(ip) {
// 检查是否为内网IP
if (isPrivateIP(ip)) {
return "内网 内网";
}
// 检查缓存
const now = Date.now();
if (ipGeolocationCache[ip] && (now - ipGeolocationCache[ip].timestamp) < GEOLOCATION_CACHE_EXPIRY) {
return ipGeolocationCache[ip].location;
}
try {
// 使用whois.pconline.com.cn API获取IP地理位置
const url = `https://whois.pconline.com.cn/ipJson.jsp?ip=${ip}&json=true`;
const response = await fetch(url, {
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
// 解析响应数据
const data = await response.json();
let location = "未知 未知";
if (data && data.country && data.city) {
location = `${data.country} ${data.city}`;
}
// 保存到缓存
ipGeolocationCache[ip] = {
location: location,
timestamp: now
};
return location;
} catch (error) {
console.error('获取IP地理位置失败:', error);
return "未知 未知";
}
}
// 检查是否为内网IP
function isPrivateIP(ip) {
const parts = ip.split('.');
// 检查IPv4内网地址
if (parts.length === 4) {
const first = parseInt(parts[0]);
const second = parseInt(parts[1]);
// 10.0.0.0/8
if (first === 10) {
return true;
}
// 172.16.0.0/12
if (first === 172 && second >= 16 && second <= 31) {
return true;
}
// 192.168.0.0/16
if (first === 192 && second === 168) {
return true;
}
// 127.0.0.0/8 (localhost)
if (first === 127) {
return true;
}
// 169.254.0.0/16 (link-local)
if (first === 169 && second === 254) {
return true;
}
}
// 检查IPv6内网地址
if (ip.includes(':')) {
// ::1/128 (localhost)
if (ip === '::1' || ip.startsWith('0:0:0:0:0:0:0:1')) {
return true;
}
// fc00::/7 (unique local address)
if (ip.startsWith('fc') || ip.startsWith('fd')) {
return true;
}
// fe80::/10 (link-local)
if (ip.startsWith('fe80:')) {
return true;
}
}
return false;
}
// 跟踪器数据库缓存
let trackersDatabase = null;
let trackersLoaded = false;
@@ -838,35 +935,44 @@ async function updateLogsTable(logs) {
`;
} else {
// 桌面设备显示完整信息
row.innerHTML = `
<td class="py-3 px-4">
<div class="text-sm font-medium">${formattedTime}</div>
<div class="text-xs text-gray-500 mt-1">${formattedDate}</div>
</td>
<td class="py-3 px-4 text-sm">
<div class="font-medium">${log.clientIP}</div>
<div class="text-xs text-gray-500 mt-1">${log.location || '未知 未知'}</div>
</td>
<td class="py-3 px-4 text-sm">
<div class="font-medium flex items-center relative">
${log.dnssec ? '<i class="fa fa-lock text-green-500 mr-1" title="DNSSEC已启用"></i>' : ''}
<div class="tracker-icon-container relative">
${isTracker ? '<i class="fa fa-eye text-red-500 mr-1"></i>' : '<i class="fa fa-eye-slash text-gray-300 mr-1"></i>'}
${trackerTooltip}
</div>
${log.domain}
</div>
<div class="text-xs text-gray-500 mt-1">类型: ${log.queryType}, <span class="${statusClass}">${statusText}</span>, <span class="${cacheStatusClass}">${log.fromCache ? '缓存' : '非缓存'}</span>${log.dnssec ? ', <span class="text-green-500"><i class="fa fa-lock"></i> DNSSEC</span>' : ''}${log.edns ? ', <span class="text-blue-500"><i class="fa fa-exchange"></i> EDNS</span>' : ''}</div>
<div class="text-xs text-gray-500 mt-1">DNS 服务器: ${log.dnsServer || '无'}, DNSSEC专用: ${log.dnssecServer || '无'}</div>
</td>
<td class="py-3 px-4 text-sm">${log.responseTime}ms</td>
<td class="py-3 px-4 text-sm text-center">
${isBlocked ?
`<button class="unblock-btn px-3 py-1 bg-green-500 text-white rounded-md hover:bg-green-600 transition-colors text-xs" data-domain="${log.domain}">放行</button>` :
`<button class="block-btn px-3 py-1 bg-red-500 text-white rounded-md hover:bg-red-600 transition-colors text-xs" data-domain="${log.domain}">拦截</button>`
}
</td>
`;
row.innerHTML = `
<td class="py-3 px-4">
<div class="text-sm font-medium">${formattedTime}</div>
<div class="text-xs text-gray-500 mt-1">${formattedDate}</div>
</td>
<td class="py-3 px-4 text-sm">
<div class="font-medium">${log.clientIP}</div>
<div class="text-xs text-gray-500 mt-1 location-${log.clientIP.replace(/[.:]/g, '-')}">${log.location || '未知 未知'}</div>
</td>
<td class="py-3 px-4 text-sm">
<div class="font-medium flex items-center relative">
${log.dnssec ? '<i class="fa fa-lock text-green-500 mr-1" title="DNSSEC已启用"></i>' : ''}
<div class="tracker-icon-container relative">
${isTracker ? '<i class="fa fa-eye text-red-500 mr-1"></i>' : '<i class="fa fa-eye-slash text-gray-300 mr-1"></i>'}
${trackerTooltip}
</div>
${log.domain}
</div>
<div class="text-xs text-gray-500 mt-1">类型: ${log.queryType}, <span class="${statusClass}">${statusText}</span>, <span class="${cacheStatusClass}">${log.fromCache ? '缓存' : '非缓存'}</span>${log.dnssec ? ', <span class="text-green-500"><i class="fa fa-lock"></i> DNSSEC</span>' : ''}${log.edns ? ', <span class="text-blue-500"><i class="fa fa-exchange"></i> EDNS</span>' : ''}</div>
<div class="text-xs text-gray-500 mt-1">DNS 服务器: ${log.dnsServer || '无'}, DNSSEC专用: ${log.dnssecServer || '无'}</div>
</td>
<td class="py-3 px-4 text-sm">${log.responseTime}ms</td>
<td class="py-3 px-4 text-sm text-center">
${isBlocked ?
`<button class="unblock-btn px-3 py-1 bg-green-500 text-white rounded-md hover:bg-green-600 transition-colors text-xs" data-domain="${log.domain}">放行</button>` :
`<button class="block-btn px-3 py-1 bg-red-500 text-white rounded-md hover:bg-red-600 transition-colors text-xs" data-domain="${log.domain}">拦截</button>`
}
</td>
`;
// 更新IP地理位置信息
const locationElement = row.querySelector(`.location-${log.clientIP.replace(/[.:]/g, '-')}`);
if (locationElement) {
// 调用getIpGeolocation函数获取地理位置
getIpGeolocation(log.clientIP).then(location => {
locationElement.textContent = location;
});
}
}
// 添加跟踪器图标悬停事件
@@ -1612,16 +1718,29 @@ async function showLogDetailModal(log) {
clientDetailsTitle.className = 'text-sm font-medium text-gray-700 uppercase tracking-wider';
clientDetailsTitle.textContent = '客户端详情';
// 创建客户端IP容器为后续更新地理位置做准备
const clientIPContainer = document.createElement('div');
clientIPContainer.className = 'text-sm font-medium text-gray-900';
clientIPContainer.innerHTML = `${clientIP} <span id="modal-location-${clientIP.replace(/[.:]/g, '-')}">(${location})</span>`;
const clientIPDiv = document.createElement('div');
clientIPDiv.className = 'space-y-1';
clientIPDiv.innerHTML = `
<div class="text-xs text-gray-500">IP地址</div>
<div class="text-sm font-medium text-gray-900">${clientIP} (${location})</div>
`;
clientIPDiv.appendChild(clientIPContainer);
clientDetails.appendChild(clientDetailsTitle);
clientDetails.appendChild(clientIPDiv);
// 动态更新地理位置信息
const locationElement = clientIPDiv.querySelector(`#modal-location-${clientIP.replace(/[.:]/g, '-')}`);
if (locationElement) {
getIpGeolocation(clientIP).then(location => {
locationElement.textContent = `(${location})`;
});
}
// 操作按钮区域
const actionButtons = document.createElement('div');
actionButtons.className = 'pt-4 border-t border-gray-200 flex justify-end space-x-2';