diff --git a/history-server/main.go b/history-server/main.go index 4ba38a3..4f47022 100644 --- a/history-server/main.go +++ b/history-server/main.go @@ -217,7 +217,9 @@ func handleStats(w http.ResponseWriter, r *http.Request) { total += e.TotalVisits } w.Header().Set("Content-Type", "application/json") - json.NewEncoder(w).Encode(map[string]any{"unique_urls": len(history), "total_visits": total}) + if err := json.NewEncoder(w).Encode(map[string]any{"unique_urls": len(history), "total_visits": total}); err != nil { + log.Printf("stats response: %v", err) + } } func normalizeURL(raw string) (string, error) { @@ -485,10 +487,7 @@ func rebuildDashySections() { if navHosts[strings.ToLower(hostOf(e.URL))] { continue // 已是导航项,不重复进历史 } - title := e.Title - if title == "" { - title = e.URL - } + title := friendlyHistoryTitle(e.Title, e.URL) icon := "fas fa-globe" if hp := hostPortOf(e.URL); hp != "" { if name := cachedFavicon(hp); name != "" { @@ -525,6 +524,26 @@ func rebuildDashySections() { os.Rename(tmp, confFile) } +// friendlyHistoryTitle 避免把历史项标题直接显示成长 URL。 +// 浏览器不给标题、或标题本身就是 URL 时,改用去掉 www. 的简洁域名。 +func friendlyHistoryTitle(title, rawURL string) string { + clean := strings.TrimSpace(title) + low := strings.ToLower(clean) + if clean != "" && !strings.HasPrefix(low, "http://") && !strings.HasPrefix(low, "https://") { + return clean + } + if u, err := url.Parse(rawURL); err == nil { + host := strings.TrimPrefix(strings.ToLower(u.Hostname()), "www.") + if host != "" { + return host + } + } + if clean != "" { + return clean + } + return "历史站点" +} + func hostOf(rawURL string) string { if u, err := url.Parse(rawURL); err == nil { return strings.ToLower(u.Hostname()) diff --git a/history-server/main_test.go b/history-server/main_test.go new file mode 100644 index 0000000..b974f9c --- /dev/null +++ b/history-server/main_test.go @@ -0,0 +1,22 @@ +package main + +import "testing" + +func TestFriendlyHistoryTitle(t *testing.T) { + cases := []struct { + name, title, rawURL, want string + }{ + {name: "real title", title: "Docker Documentation", rawURL: "https://www.docker.com/docs/", want: "Docker Documentation"}, + {name: "missing title", rawURL: "https://www.docker.com/", want: "docker.com"}, + {name: "url title", title: "https://www.docker.com/", rawURL: "https://www.docker.com/", want: "docker.com"}, + {name: "http url title", title: "http://example.org/a", rawURL: "http://example.org/a", want: "example.org"}, + {name: "invalid fallback", rawURL: "://", want: "历史站点"}, + } + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + if got := friendlyHistoryTitle(tc.title, tc.rawURL); got != tc.want { + t.Fatalf("friendlyHistoryTitle(%q, %q) = %q; want %q", tc.title, tc.rawURL, got, tc.want) + } + }) + } +}