更新
This commit is contained in:
@@ -42,6 +42,7 @@ func (s *Server) Start() error {
|
||||
mux.HandleFunc("/api/stats", s.handleStats)
|
||||
mux.HandleFunc("/api/shield", s.handleShield)
|
||||
mux.HandleFunc("/api/shield/hosts", s.handleShieldHosts)
|
||||
mux.HandleFunc("/api/shield/blacklists", s.handleShieldBlacklists)
|
||||
mux.HandleFunc("/api/query", s.handleQuery)
|
||||
mux.HandleFunc("/api/status", s.handleStatus)
|
||||
mux.HandleFunc("/api/config", s.handleConfig)
|
||||
@@ -194,14 +195,21 @@ func (s *Server) handleHourlyStats(w http.ResponseWriter, r *http.Request) {
|
||||
func (s *Server) handleShield(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
// 处理hosts管理子路由
|
||||
if strings.HasPrefix(r.URL.Path, "/api/shield/hosts") {
|
||||
s.handleShieldHosts(w, r)
|
||||
return
|
||||
// 返回屏蔽规则的基本配置信息
|
||||
switch r.Method {
|
||||
case http.MethodGet:
|
||||
shieldInfo := map[string]interface{}{
|
||||
"updateInterval": s.globalConfig.Shield.UpdateInterval,
|
||||
"blockMethod": s.globalConfig.Shield.BlockMethod,
|
||||
"blacklistCount": len(s.globalConfig.Shield.Blacklists),
|
||||
}
|
||||
json.NewEncoder(w).Encode(shieldInfo)
|
||||
default:
|
||||
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
|
||||
}
|
||||
|
||||
// 处理远程黑名单管理子路由
|
||||
if strings.HasPrefix(r.URL.Path, "/api/shield/blacklists") {
|
||||
if strings.HasPrefix(r.URL.Path, "/shield/blacklists") {
|
||||
s.handleShieldBlacklists(w, r)
|
||||
return
|
||||
}
|
||||
@@ -268,21 +276,26 @@ func (s *Server) handleShieldBlacklists(w http.ResponseWriter, r *http.Request)
|
||||
// 处理更新单个黑名单
|
||||
if strings.Contains(r.URL.Path, "/update") {
|
||||
if r.Method == http.MethodPost {
|
||||
// 提取黑名单ID
|
||||
// 提取黑名单URL或Name
|
||||
parts := strings.Split(r.URL.Path, "/")
|
||||
var id string
|
||||
var targetURLOrName string
|
||||
for i, part := range parts {
|
||||
if part == "blacklists" && i+1 < len(parts) && parts[i+1] != "update" {
|
||||
id = parts[i+1]
|
||||
targetURLOrName = parts[i+1]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if targetURLOrName == "" {
|
||||
http.Error(w, "黑名单标识不能为空", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// 获取黑名单列表
|
||||
blacklists := s.shieldManager.GetBlacklists()
|
||||
var targetIndex = -1
|
||||
for i, list := range blacklists {
|
||||
if list.URL == id || list.Name == id {
|
||||
if list.URL == targetURLOrName || list.Name == targetURLOrName {
|
||||
targetIndex = i
|
||||
break
|
||||
}
|
||||
@@ -293,18 +306,13 @@ func (s *Server) handleShieldBlacklists(w http.ResponseWriter, r *http.Request)
|
||||
return
|
||||
}
|
||||
|
||||
// 尝试更新该黑名单
|
||||
if err := s.shieldManager.fetchRemoteRules(blacklists[targetIndex].URL); err != nil {
|
||||
// 更新失败,但不返回错误,而是更新状态
|
||||
// 更新时间戳
|
||||
blacklists[targetIndex].LastUpdateTime = time.Now().Format(time.RFC3339)
|
||||
} else {
|
||||
// 更新成功
|
||||
blacklists[targetIndex].LastUpdateTime = time.Now().Format(time.RFC3339)
|
||||
// 重新加载规则
|
||||
s.shieldManager.LoadRules()
|
||||
}
|
||||
|
||||
// 保存更新后的黑名单列表
|
||||
s.shieldManager.UpdateBlacklist(blacklists)
|
||||
// 重新加载规则以获取最新的远程规则
|
||||
s.shieldManager.LoadRules()
|
||||
|
||||
json.NewEncoder(w).Encode(map[string]string{"status": "success"})
|
||||
return
|
||||
}
|
||||
@@ -372,8 +380,7 @@ func (s *Server) handleShieldBlacklists(w http.ResponseWriter, r *http.Request)
|
||||
blacklists = append(blacklists, newEntry)
|
||||
s.shieldManager.UpdateBlacklist(blacklists)
|
||||
|
||||
// 尝试获取规则
|
||||
s.shieldManager.fetchRemoteRules(req.URL)
|
||||
// 重新加载规则以获取新添加的远程规则
|
||||
s.shieldManager.LoadRules()
|
||||
|
||||
json.NewEncoder(w).Encode(map[string]string{"status": "success"})
|
||||
@@ -382,8 +389,7 @@ func (s *Server) handleShieldBlacklists(w http.ResponseWriter, r *http.Request)
|
||||
// 更新所有远程黑名单
|
||||
blacklists := s.shieldManager.GetBlacklists()
|
||||
for i := range blacklists {
|
||||
// 尝试更新每个黑名单
|
||||
s.shieldManager.fetchRemoteRules(blacklists[i].URL)
|
||||
// 更新每个黑名单的时间戳
|
||||
blacklists[i].LastUpdateTime = time.Now().Format(time.RFC3339)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// 全局配置
|
||||
const API_BASE_URL = '/api';
|
||||
const API_BASE_URL = '.';
|
||||
|
||||
// DOM 加载完成后执行
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
@@ -65,7 +65,7 @@ if (typeof window.showNotification === 'undefined') {
|
||||
// 加载初始数据(主要用于服务器状态)
|
||||
function loadInitialData() {
|
||||
// 加载服务器状态
|
||||
fetch(`${API_BASE_URL}/status`)
|
||||
fetch(`${API_BASE_URL}/api/status`)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
// 更新服务器状态指示器
|
||||
|
||||
@@ -28,7 +28,7 @@ function loadBlacklists() {
|
||||
const tbody = document.getElementById('blacklists-table').querySelector('tbody');
|
||||
showLoading(tbody);
|
||||
|
||||
apiRequest('/shield')
|
||||
apiRequest('/api/shield/blacklists')
|
||||
.then(data => {
|
||||
renderBlacklists(data);
|
||||
})
|
||||
@@ -123,9 +123,9 @@ function addBlacklist() {
|
||||
return;
|
||||
}
|
||||
|
||||
apiRequest('/shield', 'POST', { name: name, url: url })
|
||||
apiRequest('/api/shield/blacklists', 'POST', { name: name, url: url })
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
if (data.status === 'success') {
|
||||
window.showNotification('远程黑名单添加成功', 'success');
|
||||
nameInput.value = '';
|
||||
urlInput.value = '';
|
||||
@@ -142,9 +142,9 @@ function addBlacklist() {
|
||||
|
||||
// 更新远程黑名单
|
||||
function updateBlacklist(id) {
|
||||
apiRequest(`/shield/${id}/update`, 'POST')
|
||||
apiRequest(`/api/shield/blacklists/${id}/update`, 'POST')
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
if (data.status === 'success') {
|
||||
window.showNotification('远程黑名单更新成功', 'success');
|
||||
loadBlacklists();
|
||||
} else {
|
||||
@@ -162,9 +162,9 @@ function updateAllBlacklists() {
|
||||
confirmAction(
|
||||
'确定要更新所有远程黑名单吗?这可能需要一些时间。',
|
||||
() => {
|
||||
apiRequest('/shield/update-all', 'POST')
|
||||
apiRequest('/api/shield/blacklists', 'PUT')
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
if (data.status === 'success') {
|
||||
window.showNotification('所有远程黑名单更新成功', 'success');
|
||||
loadBlacklists();
|
||||
} else {
|
||||
@@ -181,9 +181,9 @@ function updateAllBlacklists() {
|
||||
|
||||
// 删除远程黑名单
|
||||
function deleteBlacklist(id) {
|
||||
apiRequest(`/shield/${id}`, 'DELETE')
|
||||
apiRequest(`/api/shield/blacklists/${id}`, 'DELETE')
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
if (data.status === 'success') {
|
||||
window.showNotification('远程黑名单删除成功', 'success');
|
||||
loadBlacklists();
|
||||
} else {
|
||||
|
||||
@@ -191,7 +191,7 @@ function updateDomainRankings() {
|
||||
// 更新统计卡片数据
|
||||
function updateStatCards() {
|
||||
// 获取所有统计数据
|
||||
apiRequest('/stats')
|
||||
apiRequest('/api/stats')
|
||||
.then(data => {
|
||||
// 更新请求统计
|
||||
if (data && data.dns) {
|
||||
@@ -239,7 +239,7 @@ function updateStatCards() {
|
||||
});
|
||||
|
||||
// 获取规则数
|
||||
apiRequest('/shield')
|
||||
apiRequest('/api/shield')
|
||||
.then(data => {
|
||||
let rulesCount = 0;
|
||||
|
||||
@@ -285,7 +285,7 @@ function updateStatCards() {
|
||||
});
|
||||
|
||||
// 获取Hosts条目数量
|
||||
apiRequest('/shield/hosts')
|
||||
apiRequest('/api/shield/hosts')
|
||||
.then(data => {
|
||||
let hostsCount = 0;
|
||||
|
||||
@@ -318,7 +318,7 @@ function updateStatCards() {
|
||||
});
|
||||
|
||||
// 获取Hosts条目数
|
||||
apiRequest('/shield/hosts')
|
||||
apiRequest('/api/shield/hosts')
|
||||
.then(data => {
|
||||
let hostsCount = 0;
|
||||
if (Array.isArray(data)) {
|
||||
@@ -834,7 +834,7 @@ function loadTopBlockedDomains(isUpdate = false) {
|
||||
tbody.innerHTML = `<td colspan="100%" style="color: #7f8c8d; font-style: italic;">加载中...</td>`;
|
||||
}
|
||||
|
||||
return apiRequest('/top-blocked')
|
||||
return apiRequest('/api/top-blocked')
|
||||
.then(data => {
|
||||
// 处理多种可能的数据格式,特别优化对用户提供格式的支持
|
||||
let processedData = [];
|
||||
@@ -909,7 +909,7 @@ function loadTopResolvedDomains(isUpdate = false) {
|
||||
tbody.innerHTML = `<td colspan="100%" style="color: #7f8c8d; font-style: italic;">加载中...</td>`;
|
||||
}
|
||||
|
||||
return apiRequest('/top-resolved')
|
||||
return apiRequest('/api/top-resolved')
|
||||
.then(data => {
|
||||
// 处理多种可能的数据格式
|
||||
let processedData = [];
|
||||
|
||||
@@ -29,7 +29,7 @@ function loadHosts() {
|
||||
showLoading(tbody);
|
||||
|
||||
// 更新API路径,使用完整路径
|
||||
apiRequest('/shield/hosts', 'GET')
|
||||
apiRequest('/api/shield/hosts', 'GET')
|
||||
.then(data => {
|
||||
// 处理不同格式的响应数据
|
||||
let hostsData;
|
||||
@@ -156,7 +156,7 @@ function addHostsEntry() {
|
||||
}
|
||||
|
||||
// 修复重复API调用问题,只调用一次
|
||||
apiRequest('/shield/hosts', 'POST', { ip: ip, domain: domain })
|
||||
apiRequest('/api/shield/hosts', 'POST', { ip: ip, domain: domain })
|
||||
.then(data => {
|
||||
// 处理不同的响应格式
|
||||
if (data.success || data.status === 'success') {
|
||||
@@ -209,7 +209,7 @@ function deleteHostsEntry(ip, domain) {
|
||||
}
|
||||
|
||||
// 更新API路径
|
||||
apiRequest('/shield/hosts', 'DELETE', { ip: ip, domain: domain })
|
||||
apiRequest('/api/shield/hosts', 'DELETE', { ip: ip, domain: domain })
|
||||
.then(data => {
|
||||
// 处理不同的响应格式
|
||||
if (data.success || data.status === 'success') {
|
||||
|
||||
@@ -40,7 +40,7 @@ function runDnsQuery() {
|
||||
showQueryLoading();
|
||||
|
||||
// 更新API路径,使用完整路径
|
||||
apiRequest('/query', 'GET', { domain: domain })
|
||||
apiRequest('/api/query', 'GET', { domain: domain })
|
||||
.then(data => {
|
||||
// 处理可能的不同响应格式
|
||||
renderQueryResult(data);
|
||||
|
||||
@@ -41,7 +41,7 @@ async function loadRules() {
|
||||
showLoading(rulesPanel);
|
||||
|
||||
// 更新API路径,使用正确的API路径
|
||||
const data = await apiRequest('/shield', 'GET');
|
||||
const data = await apiRequest('/api/shield', 'GET');
|
||||
|
||||
// 处理后端返回的复杂对象数据格式
|
||||
let allRules = [];
|
||||
@@ -207,7 +207,7 @@ async function addNewRule() {
|
||||
const processedRule = preprocessRule(rule);
|
||||
|
||||
// 使用正确的API路径
|
||||
const response = await apiRequest('/shield', 'POST', { rule: processedRule });
|
||||
const response = await apiRequest('/api/shield', 'POST', { rule: processedRule });
|
||||
|
||||
// 处理不同的响应格式
|
||||
if (response.success || response.status === 'success') {
|
||||
@@ -258,7 +258,7 @@ async function deleteRule(index) {
|
||||
}
|
||||
|
||||
// 使用正确的API路径
|
||||
const response = await apiRequest('/shield', 'DELETE', { rule });
|
||||
const response = await apiRequest('/api/shield', 'DELETE', { rule });
|
||||
|
||||
// 处理不同的响应格式
|
||||
if (response.success || response.status === 'success') {
|
||||
@@ -319,8 +319,8 @@ async function reloadRules() {
|
||||
const rulesPanel = document.getElementById('rules-panel');
|
||||
showLoading(rulesPanel);
|
||||
|
||||
// 使用正确的API路径和方法 - PUT请求到/shield
|
||||
await apiRequest('/shield', 'PUT');
|
||||
// 使用正确的API路径和方法 - PUT请求到/api/shield
|
||||
await apiRequest('/api/shield', 'PUT');
|
||||
|
||||
// 重新加载规则列表
|
||||
await loadRules();
|
||||
|
||||
Reference in New Issue
Block a user