feat: 文章全文提取 + 移除图片代理#12
Merged
Merged
Conversation
- 默认显示文章摘要,用户可选择展开完整内容 - 智能判断是否显示切换按钮(摘要长度、内容差异等) - 切换文章时自动重置为摘要视图 - 改善阅读体验,节省流量和加载时间
当 RSS feed 只包含摘要时,用户可点击"展开全文"按钮从原网站提取完整内容。 主要更改: - 后端:使用 Mozilla Readability + linkedom 提取文章正文 - 安全:域名白名单、SSRF 防护、速率限制(10次/分钟) - 前端:IndexedDB 缓存(24小时)、加载动画、优雅降级 - 双部署:同时支持 Vercel 和 Cloudflare Pages 新增文件: - server/utils/readability.ts - Readability 包装器 - server/handlers/article-extract.ts - 核心处理器 - api/article/extract.ts - Vercel 包装器 - functions/api/article/extract.ts - Cloudflare 包装器 - src/services/articleService.ts - 前端 API 客户端 - docs/article-extraction.md - 功能文档 修改文件: - components/ArticleReader.tsx - 集成提取功能 - types.ts - 添加类型定义 - server/env.ts - 添加环境变量 - wrangler.toml - 添加环境变量配置 依赖: - linkedom@0.18.5 - @mozilla/readability@0.5.0
简化按钮显示逻辑:只要文章摘要长度 >= 100 字符就显示按钮, 不再要求 content 字段必须存在。这样可以支持只有摘要的文章。
优先使用 RSS feed 中已有的 content:encoded 全文(零服务端调用), 其次通过 mode=raw 轻量代理获取 HTML 在浏览器端用 Readability 解析, 最后回退到 RSS 内容,最大限度减少 Cloudflare Pages Functions 请求配额消耗。
原逻辑使用 description 长度 >= 100 字符作为判断条件, 导致描述较短但确实被截断的文章(如少数派的单句摘要) 无法显示展开全文按钮。改为只要文章有原文链接即显示按钮。
- 删除 MediaUrl 接口、ImageProxyMode 类型及相关工具函数 - Article.thumbnail 和 Feed.image 类型从 MediaUrl 简化为 string - 移除 rssService 中的代理模式管理代码(6个函数/变量) - 移除 AppContext 中的 imageProxyMode 状态和 localStorage 持久化 - 移除 SettingsModal 中的「媒体代理策略」设置卡片 - 组件层删除 getMediaUrl()/proxyImageUrl() 调用,直接使用 URL - 删除服务端代理端点:api/media/proxy、functions/api/media/proxy、 server/handlers/media-proxy - 服务端 feeds API 响应移除 canProxyImages 字段 图片本身无 CORS 限制,浏览器可直连加载,无需服务端中转。 此项优化预计减少 60-80% 的 Workers 请求量。
- article/extract 和 history 端点改用 createRateLimiter()(内存实现), 不再消耗 KV 读写额度(免费额度仅 1K 写/天) - repository.getAllAllowedMediaHosts() 添加模块级缓存(5分钟 TTL), 避免每次请求都全表扫描 feeds - Vercel 端 api/article/extract.ts 同样添加白名单缓存
- 新建 src/services/corsProxy.ts 共享 CORS 代理模块(4 个公共代理, 带超时和响应验证) - readabilityService.fetchAndExtractClientSide() 改为两层策略: 1. 先尝试公共 CORS 代理获取 HTML(零服务端开销) 2. 失败后 fallback 到 /api/article/extract 服务端端点
代理设置已删除,该标签页无剩余可交互内容,直接移除。
- CLAUDE.md: 移除 MediaUrl/ImageProxyMode 相关描述,添加文章提取相关文件和端点,更新环境变量 - README.md: 移除双 URL 媒体架构和代理模式描述,添加文章全文提取功能说明和 API 端点 - 删除过时的 docs/article-extraction.md 和 docs/article-extraction-summary.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
MediaUrl、ImageProxyMode、/api/media/proxy),图片改为浏览器直连加载Changes
新增文件
src/services/articleService.ts— 文章提取入口 + IndexedDB 缓存(24h TTL)src/services/readabilityService.ts— 客户端 DOMParser + Readability 解析src/services/corsProxy.ts— 公共 CORS 代理列表,自动逐一回退server/handlers/article-extract.ts— 服务端提取处理器(速率限制 + 域名白名单)server/utils/readability.ts— 服务端 linkedom + Readability 包装api/article/extract.ts— Vercel 端点functions/api/article/extract.ts— Cloudflare 端点删除文件
api/media/proxy.ts、server/handlers/media-proxy.ts、functions/api/media/proxy.tsdocs/article-extraction.md、docs/article-extraction-summary.md修改文件
components/ArticleReader.tsx— 集成全文提取 UI(展开/收起、加载动画、错误回退)types.ts— 移除MediaUrl/ImageProxyMode,新增ExtractedArticle/ArticleExtractionResponseservices/rssService.ts— 移除图片代理逻辑,改用 CORS 代理获取自定义 RSSlib/AppContext.tsx、components/SettingsModal.tsx— 移除代理模式设置Test plan
npm run build编译通过