From e933c71b3df827b7cb8e5895a09761067365e308 Mon Sep 17 00:00:00 2001 From: wxs Date: Tue, 3 Mar 2026 15:55:06 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=93=94=E5=93=A9?= =?UTF-8?q?=E5=93=94=E5=93=A9=E5=B9=B3=E5=8F=B0=E5=B0=81=E9=9D=A2=E5=9B=BE?= =?UTF-8?q?=E6=97=A0=E6=B3=95=E6=98=BE=E7=A4=BA=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 后端 Bilibili 适配器添加 URL 规范化,处理协议相对路径和 http 协议 - 前端 Image 组件添加 referrerPolicy="no-referrer" 绕过 CDN 防盗链 Co-Authored-By: Claude Opus 4.6 --- packages/backend/src/lib/adapters/bilibili.ts | 11 +++++++++-- packages/frontend/src/components/card/ContentCard.tsx | 2 ++ .../frontend/src/components/detail/DetailPanel.tsx | 2 ++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/packages/backend/src/lib/adapters/bilibili.ts b/packages/backend/src/lib/adapters/bilibili.ts index 749ab54..2ea0a41 100644 --- a/packages/backend/src/lib/adapters/bilibili.ts +++ b/packages/backend/src/lib/adapters/bilibili.ts @@ -1,6 +1,13 @@ import type { ContentItem, PlatformAdapter } from "@muse/shared"; import { tikhubFetch } from "../tikhub"; +/** Ensure Bilibili URLs use https:// (API may return protocol-relative "//..." or http) */ +function normalizeUrl(url: string): string { + if (url.startsWith("//")) return `https:${url}`; + if (url.startsWith("http://")) return url.replace("http://", "https://"); + return url; +} + export class BilibiliAdapter implements PlatformAdapter { async fetchTrending(count: number): Promise { // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -44,10 +51,10 @@ export class BilibiliAdapter implements PlatformAdapter { return { id: String(aid || bvid), title: raw?.title || "无标题", - cover_url: raw?.pic || undefined, + cover_url: raw?.pic ? normalizeUrl(raw.pic) : undefined, video_url: undefined, author_name: owner?.name || raw?.author || "未知作者", - author_avatar: owner?.face || undefined, + author_avatar: owner?.face ? normalizeUrl(owner.face) : undefined, play_count: stat?.view ?? undefined, like_count: stat?.like ?? undefined, collect_count: stat?.favorite ?? undefined, diff --git a/packages/frontend/src/components/card/ContentCard.tsx b/packages/frontend/src/components/card/ContentCard.tsx index 3ff62fa..e91f4c5 100644 --- a/packages/frontend/src/components/card/ContentCard.tsx +++ b/packages/frontend/src/components/card/ContentCard.tsx @@ -35,6 +35,7 @@ export function ContentCard({ item }: ContentCardProps) { alt={item.title} fill unoptimized + referrerPolicy="no-referrer" className="object-cover" loading="lazy" sizes="(max-width: 640px) 100vw, (max-width: 960px) 50vw, (max-width: 1240px) 33vw, 25vw" @@ -84,6 +85,7 @@ export function ContentCard({ item }: ContentCardProps) { width={20} height={20} unoptimized + referrerPolicy="no-referrer" className="rounded-full object-cover" onError={(e) => { (e.target as HTMLImageElement).style.display = "none"; diff --git a/packages/frontend/src/components/detail/DetailPanel.tsx b/packages/frontend/src/components/detail/DetailPanel.tsx index b58f8ba..6bbf0d7 100644 --- a/packages/frontend/src/components/detail/DetailPanel.tsx +++ b/packages/frontend/src/components/detail/DetailPanel.tsx @@ -46,6 +46,7 @@ export function DetailPanel({ item }: DetailPanelProps) { alt={item.title} fill unoptimized + referrerPolicy="no-referrer" className="object-cover" priority sizes="(max-width: 768px) 100vw, 768px" @@ -87,6 +88,7 @@ export function DetailPanel({ item }: DetailPanelProps) { width={40} height={40} unoptimized + referrerPolicy="no-referrer" className="rounded-full object-cover" onError={(e) => { (e.target as HTMLImageElement).style.display = "none";