判断文件能否预览的核心是依据真实 mime 类型与白名单校验,而非扩展名;需流式读取、编码检测、截断控制;pdf/图片须生成轻量缩略图并异步处理;preview 接口应拆分为元信息与内容两个路由以提升缓存与性能。

怎么判断一个文件能不能预览
核心是看文件内容是否能被安全转成文本或标准格式,而不是只看后缀名。比如 .txt 肯定行,但 .docx 需解压+解析 XML,.pdf 得调用解析库,而 .exe 或加密的 .zip 就不该进预览流程。
实操建议:
- 先用
mimetype库(如github.com/gabriel-vasile/mimetype)读取文件前 512 字节,识别真实类型,比filepath.Ext可靠得多 - 维护一个白名单:只允许
text/*、application/json、application/xml、image/*(缩略图)、application/pdf等明确支持的类型 - 对
application/octet-stream这类泛型类型,直接拒绝,不尝试猜测 - 特别注意:PDF 和 Office 文档要加超时和内存限制,否则恶意构造的大文件会卡死服务
文本文件怎么安全读取和截断
不能直接 os.ReadFile 整个文件——用户上传 2GB 的日志文件会把内存打爆。得流式读、按需截、防编码乱码。
实操建议:
- 用
bufio.NewReader+io.LimitReader控制最大读取字节数(比如 1MB),超过就截断并标记“已截断” - 检测编码用
golang.org/x/text/encoding+charset库,优先试UTF-8,失败再 fallback 到GBK(中文场景),别硬转 - 换行统一处理成
\n,避免前端渲染错乱;行数限制建议设为 1000 行,不是字节数 - 敏感路径(如
/etc/passwd)或含控制字符(\x00-\x08、\x0E-\x1F)的内容,直接返回空或报错,不清洗后展示
PDF 和图片怎么生成轻量预览
PDF 不渲染全文,图片不原图返回——目标是快、小、可缓存。重点不在“还原”,而在“够看”。
Colly 是一个用于 Go 语言的快速开源爬取和爬虫框架。它适用于从简单的页面提取到异步爬虫处理大量页面集合,支持请求回调和结构化解析。
实操建议:
- Pdf:用
github.com/unidoc/unipdf/v3/creator或更轻的github.com/jung-kurt/gofpdf提取第一页为 PNG,尺寸固定为800x1200,质量压缩到 75%,超时设为 3 秒 - 图片:用
github.com/disintegration/imaging缩放,保持宽高比,最长边不超过 1200px;WebP 格式优先(体积小),但 IE 用户降级为 JPEG - 所有缩略图加
Cache-Control: public, max-age=86400,路径里嵌入文件 hash(如/thumb/<code>sha256.webp),避免 CDN 缓存错乱 - 别在 HTTP handler 里实时生成——先异步写入
/tmp/thumbs/或对象存储,再 302 跳转,不然并发一高就堵住
为什么 preview 接口要拆成两个路由
一个返回元信息(能否预览、类型、大小、页数),一个返回实际内容(文本片段或缩略图 URL)。合在一个接口里,会导致缓存失效、CDN 不友好、前端逻辑耦合。
实操建议:
- 元信息接口如
GET /api/v1/preview/meta?file_id=abc123,响应快(can_preview、mime_type、page_count(PDF)、is_truncated - 内容接口如
GET /api/v1/preview/content?file_id=abc123&type=text或GET /api/v1/preview/thumb?file_id=abc123,不缓存或短缓存,带鉴权校验 - 前端必须先调 meta,再决定要不要发 content 请求——避免对不可预览文件浪费一次网络请求
- meta 接口要记录
user_agent和referer,方便后续识别爬虫或异常批量请求
最麻烦的其实是 PDF 的字体嵌入和权限位检查——有些 PDF 设置了“禁止复制文字”,unipdf 默认会报错,得提前用 pdfcpu 检查 pdfcpu validate 并跳过这类文件。这事容易漏,上线后才发现部分 PDF 打不开。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










