Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions lib/notion/getPostBlocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
// 移除同步块
Expand Down Expand Up @@ -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,已覆盖
}
Loading