web异常待修复

This commit is contained in:
Alex Yang
2025-11-24 10:50:03 +08:00
parent 534878fa4d
commit 4467a0bf4c
14 changed files with 30715 additions and 243 deletions

View File

@@ -2,6 +2,12 @@
function initQueryPanel() {
// 初始化事件监听器
initQueryEventListeners();
// 确保结果容器默认隐藏
const resultContainer = document.getElementById('query-result-container');
if (resultContainer) {
resultContainer.classList.add('hidden');
}
}
// 初始化事件监听器
@@ -23,7 +29,9 @@ function runDnsQuery() {
const domain = domainInput.value.trim();
if (!domain) {
window.showNotification('请输入要查询的域名', 'warning');
if (typeof window.showNotification === 'function') {
window.showNotification('请输入要查询的域名', 'warning');
}
domainInput.focus();
return;
}
@@ -31,62 +39,110 @@ function runDnsQuery() {
// 显示查询中状态
showQueryLoading();
apiRequest('/query?domain=' + domain, 'GET', { domain: domain })
// 更新API路径使用完整路径
apiRequest('/query', 'GET', { domain: domain })
.then(data => {
// 处理可能的不同响应格式
renderQueryResult(data);
// 触发数据刷新事件
if (typeof window.triggerDataRefresh === 'function') {
window.triggerDataRefresh('query');
}
})
.catch(error => {
console.error('DNS查询失败:', error);
showQueryError('查询失败,请稍后重试');
window.showNotification('DNS查询失败', 'error');
if (typeof window.showNotification === 'function') {
window.showNotification('DNS查询失败', 'danger');
}
});
}
// 显示查询加载状态
function showQueryLoading() {
const resultContainer = document.getElementById('query-result-container');
resultContainer.classList.remove('hidden');
if (!resultContainer) return;
// 添加加载动画类
resultContainer.classList.add('loading-animation');
resultContainer.classList.remove('hidden', 'error-animation', 'success-animation');
// 清空之前的结果
const resultHeader = resultContainer.querySelector('.result-header h3');
const resultContent = resultContainer.querySelector('.result-content');
resultHeader.textContent = '查询中...';
resultContent.innerHTML = '<div class="loading"></div>';
if (resultHeader) resultHeader.textContent = '查询中...';
if (resultContent) {
resultContent.innerHTML = '<div class="loading">' +
'<div class="spinner"></div><span>正在查询...</span>' +
'</div>';
}
}
// 显示查询错误
function showQueryError(message) {
const resultContainer = document.getElementById('query-result-container');
resultContainer.classList.remove('hidden');
if (!resultContainer) return;
// 添加错误动画类
resultContainer.classList.add('error-animation');
resultContainer.classList.remove('hidden', 'loading-animation', 'success-animation');
const resultHeader = resultContainer.querySelector('.result-header h3');
const resultContent = resultContainer.querySelector('.result-content');
resultHeader.textContent = '查询错误';
resultContent.innerHTML = `<div class="result-item" style="color: #e74c3c;">${message}</div>`;
if (resultHeader) resultHeader.textContent = '查询错误';
if (resultContent) {
resultContent.innerHTML = `<div class="result-item error-message">
<i class="fas fa-exclamation-circle"></i>
<span>${message}</span>
</div>`;
}
}
// 渲染查询结果
function renderQueryResult(result) {
const resultContainer = document.getElementById('query-result-container');
resultContainer.classList.remove('hidden');
if (!resultContainer) return;
// 添加成功动画类
resultContainer.classList.add('success-animation');
resultContainer.classList.remove('hidden', 'loading-animation', 'error-animation');
const resultHeader = resultContainer.querySelector('.result-header h3');
const resultContent = resultContainer.querySelector('.result-content');
resultHeader.textContent = '查询结果';
if (resultHeader) resultHeader.textContent = '查询结果';
if (!resultContent) return;
// 安全的HTML转义函数
function escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
// 根据查询结果构建内容
let content = '';
let content = '<div class="result-grid">';
// 域名
content += `<div class="result-item"><strong>域名:</strong> <span id="result-domain">${result.domain || ''}</span></div>`;
const safeDomain = escapeHtml(result.domain || '');
content += `<div class="result-item domain-item">
<div class="result-label"><i class="fas fa-globe"></i> 域名</div>
<div class="result-value" id="result-domain">${safeDomain}</div>
</div>`;
// 状态
const statusText = result.isBlocked ? '被屏蔽' : result.isAllowed ? '允许访问' : '未知';
const statusClass = result.isBlocked ? 'status-error' : result.isAllowed ? 'status-success' : '';
content += `<div class="result-item"><strong>状态:</strong> <span id="result-status" class="${statusClass}">${statusText}</span></div>`;
const statusIcon = result.isBlocked ? 'fa-ban' : result.isAllowed ? 'fa-check-circle' : 'fa-question-circle';
content += `<div class="result-item status-item">
<div class="result-label"><i class="fas fa-shield-alt"></i> 状态</div>
<div class="result-value" id="result-status" class="${statusClass}">
<i class="fas ${statusIcon}"></i> ${statusText}
</div>
</div>`;
// 规则类型
let ruleType = '';
@@ -101,45 +157,123 @@ function renderQueryResult(result) {
} else {
ruleType = result.isWhitelist ? '白名单规则' : result.isHosts ? 'Hosts记录' : '未匹配任何规则';
}
content += `<div class="result-item"><strong>规则类型:</strong> <span id="result-rule-type">${ruleType}</span></div>`;
content += `<div class="result-item rule-type-item">
<div class="result-label"><i class="fas fa-list-alt"></i> 规则类型</div>
<div class="result-value" id="result-rule-type">${escapeHtml(ruleType)}</div>
</div>`;
// 匹配规则
const matchedRule = result.matchedRule || '无';
content += `<div class="result-item"><strong>匹配规则:</strong> <span id="result-rule">${matchedRule}</span></div>`;
const matchedRule = escapeHtml(result.matchedRule || '无');
content += `<div class="result-item matched-rule-item">
<div class="result-label"><i class="fas fa-sitemap"></i> 匹配规则</div>
<div class="result-value rule-code" id="result-rule">${matchedRule}</div>
</div>`;
// Hosts记录
const hostsRecord = result.hostsRecord ? `${result.hostsRecord.ip} ${result.hostsRecord.domain}` : '无';
content += `<div class="result-item"><strong>Hosts记录:</strong> <span id="result-hosts">${hostsRecord}</span></div>`;
const hostsRecord = result.hostsRecord ?
escapeHtml(`${result.hostsRecord.ip} ${result.hostsRecord.domain}`) : '无';
content += `<div class="result-item hosts-item">
<div class="result-label"><i class="fas fa-file-alt"></i> Hosts记录</div>
<div class="result-value" id="result-hosts">${hostsRecord}</div>
</div>`;
// 查询时间
const queryTime = `${(result.queryTime || 0).toFixed(2)} ms`;
content += `<div class="result-item"><strong>查询时间:</strong> <span id="result-time">${queryTime}</span></div>`;
content += `<div class="result-item time-item">
<div class="result-label"><i class="fas fa-clock"></i> 查询时间</div>
<div class="result-value" id="result-time">${queryTime}</div>
</div>`;
content += '</div>'; // 结束result-grid
// DNS响应如果有
if (result.dnsResponse) {
content += '<div class="result-item"><strong>DNS响应:</strong></div>';
content += '<div class="dns-response">';
content += '<div class="dns-response-section">';
content += '<h4><i class="fas fa-exchange-alt"></i> DNS响应</h4>';
if (result.dnsResponse.answers && result.dnsResponse.answers.length > 0) {
content += '<ul>';
result.dnsResponse.answers.forEach(answer => {
content += `<li>${answer.name} ${answer.type} ${answer.value}</li>`;
content += '<div class="dns-answers">';
result.dnsResponse.answers.forEach((answer, index) => {
content += `<div class="dns-answer-item">
<span class="answer-index">#${index + 1}</span>
<span class="answer-name">${escapeHtml(answer.name)}</span>
<span class="answer-type">${escapeHtml(answer.type)}</span>
<span class="answer-value">${escapeHtml(answer.value)}</span>
</div>`;
});
content += '</ul>';
content += '</div>';
} else {
content += '<p>无DNS响应记录</p>';
content += '<div class="empty-dns"><i class="fas fa-info-circle"></i> 无DNS响应记录</div>';
}
content += '</div>';
}
// 添加复制功能
content += `<div class="result-actions">
<button class="btn btn-sm btn-secondary" onclick="copyQueryResult()">
<i class="fas fa-copy"></i> 复制结果
</button>
</div>`;
resultContent.innerHTML = content;
// 更新结果元素的内容(确保数据一致性)
document.getElementById('result-domain').textContent = result.domain || '';
document.getElementById('result-status').textContent = statusText;
document.getElementById('result-status').className = statusClass;
document.getElementById('result-rule-type').textContent = ruleType;
document.getElementById('result-rule').textContent = matchedRule;
document.getElementById('result-hosts').textContent = hostsRecord;
document.getElementById('result-time').textContent = queryTime;
// 通知用户查询成功
if (typeof window.showNotification === 'function') {
const statusMsg = result.isBlocked ? '查询完成,该域名被屏蔽' :
result.isAllowed ? '查询完成,该域名允许访问' : '查询完成';
window.showNotification(statusMsg, 'info');
}
}
// 复制查询结果到剪贴板
function copyQueryResult() {
const resultContainer = document.getElementById('query-result-container');
if (!resultContainer) return;
// 收集关键信息
const domain = document.getElementById('result-domain')?.textContent || '未知域名';
const status = document.getElementById('result-status')?.textContent || '未知状态';
const ruleType = document.getElementById('result-rule-type')?.textContent || '无规则类型';
const matchedRule = document.getElementById('result-rule')?.textContent || '无匹配规则';
const queryTime = document.getElementById('result-time')?.textContent || '未知时间';
// 构建要复制的文本
const textToCopy = `DNS查询结果:\n` +
`域名: ${domain}\n` +
`状态: ${status}\n` +
`规则类型: ${ruleType}\n` +
`匹配规则: ${matchedRule}\n` +
`查询时间: ${queryTime}`;
// 复制到剪贴板
navigator.clipboard.writeText(textToCopy)
.then(() => {
if (typeof window.showNotification === 'function') {
window.showNotification('查询结果已复制到剪贴板', 'success');
}
})
.catch(err => {
console.error('复制失败:', err);
if (typeof window.showNotification === 'function') {
window.showNotification('复制失败,请手动复制', 'warning');
}
});
}
// 导出函数,供其他模块调用
window.initQueryPanel = initQueryPanel;
window.runDnsQuery = runDnsQuery;
// 注册到面板导航系统
if (window.registerPanelModule) {
window.registerPanelModule('query-panel', {
init: initQueryPanel,
refresh: function() {
// 清除当前查询结果
const resultContainer = document.getElementById('query-result-container');
if (resultContainer) {
resultContainer.classList.add('hidden');
}
}
});
}