From 750dbcc7c35d66a0ef580192bc47ac848aff316a Mon Sep 17 00:00:00 2001 From: yujiangping Date: Wed, 18 Mar 2026 18:52:37 +0800 Subject: [PATCH] fix(web): improve document preview handling for .doc files and validate docx format - Add early return for .doc files with unsupported format message - Implement ZIP format validation for docx files by checking PK header bytes - Add error handling for invalid docx content with detailed error messages - Update Word preview UI to show download prompt for .doc files instead of attempting conversion - Prevent mammoth converter from processing invalid or non-docx file formats --- web/src/components/DocumentPreview/index.tsx | 37 ++++++++++++++++---- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/web/src/components/DocumentPreview/index.tsx b/web/src/components/DocumentPreview/index.tsx index fd426379..247f713e 100644 --- a/web/src/components/DocumentPreview/index.tsx +++ b/web/src/components/DocumentPreview/index.tsx @@ -4,7 +4,7 @@ * @Author: yujiangping * @Date: 2026-03-16 19:01:12 * @LastEditors: yujiangping - * @LastEditTime: 2026-03-18 18:24:27 + * @LastEditTime: 2026-03-18 18:35:53 */ import { useState, useEffect, useRef, useCallback, type FC } from 'react'; import { Spin, Alert, Button, Table, InputNumber, Image } from 'antd'; @@ -286,7 +286,20 @@ const DocumentPreview: FC = ({ setError(false); setErrorMessage(''); try { + // .doc 旧格式 mammoth 不支持,使用 Office Online Viewer + if (getFileExtension() === '.doc') { + setHtmlContent(''); + setLoading(false); + return; + } const arrayBuffer = await fetchFileBuffer(fileUrl); + // 校验是否为有效的 docx(ZIP 格式,前两字节为 PK) + const header = new Uint8Array(arrayBuffer.slice(0, 4)); + if (header[0] !== 0x50 || header[1] !== 0x4B) { + // 不是 ZIP/docx 格式,可能是 HTML 错误页或 JSON 响应 + const text = new TextDecoder().decode(arrayBuffer.slice(0, 200)); + throw new Error(`文件内容不是有效的 docx 格式: ${text.substring(0, 100)}`); + } const result = await mammoth.convertToHtml({ arrayBuffer }); setHtmlContent(result.value); setLoading(false); @@ -491,12 +504,22 @@ const DocumentPreview: FC = ({ {/* Word 预览 */} {isWordFile() && !error && !loading && ( -
-
-
+ getFileExtension() === '.doc' ? ( + /* .doc 旧格式前端无法解析,提示下载 */ +
+
+

.doc 格式暂不支持在线预览,请下载后查看

+ +
+
+ ) : ( +
+
+
+ ) )} {/* Excel 预览 */}