From c6d065026d4879f99a5a007516d391a4bda6d602 Mon Sep 17 00:00:00 2001 From: tangly1024 Date: Tue, 16 Dec 2025 22:24:46 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AF=B9=E5=BC=82=E5=B8=B8=E5=9B=BE=E7=89=87?= =?UTF-8?q?=E6=A0=BC=E5=BC=8F=E7=9A=84=E5=85=BC=E5=AE=B9=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/notion/getPostBlocks.js | 57 +++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/lib/notion/getPostBlocks.js b/lib/notion/getPostBlocks.js index 6badce53a17..1d920e92f0f 100644 --- a/lib/notion/getPostBlocks.js +++ b/lib/notion/getPostBlocks.js @@ -109,6 +109,9 @@ function convertNotionBlocksToPost(id, blockMap, slice) { count++ + // === 【新增】强制修复非法 URL === + sanitizeBlockUrls(b?.value) + if (b?.value?.type === 'sync_block' && b?.value?.children) { const childBlocks = b.value.children // 移除同步块 @@ -190,3 +193,57 @@ export const fetchInBatches = async (ids, batchSize = 100) => { } return fetchedBlocks } + + +/** + * 强制修复 block 中所有可能的非法 URL 字段 + * @param {Object} blockValue - block.value + */ +function sanitizeBlockUrls(blockValue) { + if (!blockValue || typeof blockValue !== 'object') return + + const fixUrl = (url) => { + if (typeof url !== 'string') return url + + if (url.startsWith('/')) { + return url + } + + // 修复 http:xxx → http://xxx + if (url.startsWith('http:') && !url.startsWith('http://')) { + url = 'http://' + url.slice(5) + } else if (url.startsWith('https:') && !url.startsWith('https://')) { + url = 'https://' + url.slice(6) + } + + // 再次验证是否合法,否则替换为占位图 + try { + new URL(url) + return url + } catch { + console.warn('[Sanitize URL] Invalid URL replaced:', url) + return 'https://via.placeholder.com/1x1?text=Invalid+Image' + } + } + + // 1. 处理 properties.source(用于 image, embed, bookmark, file, pdf 等) + if ( + blockValue.properties?.source?.[0]?.[0] && + typeof blockValue.properties.source[0][0] === 'string' + ) { + blockValue.properties.source[0][0] = fixUrl(blockValue.properties.source[0][0]) + } + + // 2. 处理 file.url(用于 file block) + if (blockValue.file?.url && typeof blockValue.file.url === 'string') { + blockValue.file.url = fixUrl(blockValue.file.url) + } + + // 3. 处理 format.page_cover(页面封面) + if (blockValue.format?.page_cover && typeof blockValue.format.page_cover === 'string') { + blockValue.format.page_cover = fixUrl(blockValue.format.page_cover) + } + + // 4. 处理其他可能的 URL 字段(可选扩展) + // 例如:video、audio 的 source 可能也走 properties.source,已覆盖 +} \ No newline at end of file