# TUS 上传 Hook 使用指南 ## 概述 `useTusUpload` 是一个自定义 React Hook,提供了基于 TUS 协议的文件上传功能,支持大文件上传、断点续传、进度跟踪等特性。 ## 环境变量配置 确保在 `.env` 文件中配置了以下环境变量: ```env NEXT_PUBLIC_SERVER_PORT=3000 NEXT_PUBLIC_SERVER_IP=http://localhost ``` **注意**:在 Next.js 中,客户端组件只能访问以 `NEXT_PUBLIC_` 开头的环境变量。 ## Hook API ### 返回值 ```typescript const { uploadProgress, // 上传进度 (0-100) isUploading, // 是否正在上传 uploadError, // 上传错误信息 handleFileUpload, // 文件上传函数 getFileUrlByFileId, // 根据文件ID获取访问链接 getFileInfo, // 获取文件详细信息 getUploadStatus, // 获取上传状态 serverUrl, // 服务器地址 } = useTusUpload(); ``` ### 主要方法 #### `handleFileUpload(file, onSuccess?, onError?)` 上传文件的主要方法。 **参数:** - `file: File` - 要上传的文件对象 - `onSuccess?: (result: UploadResult) => void` - 成功回调 - `onError?: (error: string) => void` - 失败回调 **返回:** `Promise` **UploadResult 接口:** ```typescript interface UploadResult { compressedUrl: string; // 压缩版本URL(当前与原始URL相同) url: string; // 文件访问URL fileId: string; // 文件唯一标识 fileName: string; // 文件名 } ``` #### `getFileUrlByFileId(fileId: string)` 根据文件ID生成访问链接。 **参数:** - `fileId: string` - 文件唯一标识 **返回:** `string` - 文件访问URL ## 使用示例 ### 基础使用 ```tsx import React, { useState } from 'react'; import { useTusUpload } from '../hooks/useTusUpload'; function UploadComponent() { const { uploadProgress, isUploading, uploadError, handleFileUpload } = useTusUpload(); const [uploadedUrl, setUploadedUrl] = useState(''); const handleFileChange = async (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (!file) return; try { const result = await handleFileUpload( file, (result) => { console.log('上传成功!', result); setUploadedUrl(result.url); }, (error) => { console.error('上传失败:', error); }, ); } catch (error) { console.error('上传出错:', error); } }; return (
{isUploading && (

上传进度: {uploadProgress}%

)} {uploadError &&

{uploadError}

} {uploadedUrl && ( 查看上传的文件 )}
); } ``` ### 拖拽上传 ```tsx import React, { useCallback, useState } from 'react'; import { useTusUpload } from '../hooks/useTusUpload'; function DragDropUpload() { const { handleFileUpload, isUploading, uploadProgress } = useTusUpload(); const [dragOver, setDragOver] = useState(false); const handleDrop = useCallback( async (e: React.DragEvent) => { e.preventDefault(); setDragOver(false); const files = e.dataTransfer.files; if (files.length > 0) { await handleFileUpload(files[0]); } }, [handleFileUpload], ); const handleDragOver = useCallback((e: React.DragEvent) => { e.preventDefault(); setDragOver(true); }, []); return (
setDragOver(false)} style={{ border: dragOver ? '2px dashed #0070f3' : '2px dashed #ccc', padding: '20px', textAlign: 'center', backgroundColor: dragOver ? '#f0f8ff' : '#fafafa', }} > {isUploading ?

上传中... {uploadProgress}%

:

拖拽文件到这里上传

}
); } ``` ### 多文件上传 ```tsx function MultiFileUpload() { const { handleFileUpload } = useTusUpload(); const [uploadingFiles, setUploadingFiles] = useState>(new Map()); const handleFilesChange = async (e: React.ChangeEvent) => { const files = e.target.files; if (!files) return; for (let i = 0; i < files.length; i++) { const file = files[i]; const fileId = `${file.name}-${Date.now()}-${i}`; setUploadingFiles((prev) => new Map(prev).set(fileId, 0)); try { await handleFileUpload( file, (result) => { console.log(`文件 ${file.name} 上传成功:`, result); setUploadingFiles((prev) => { const newMap = new Map(prev); newMap.delete(fileId); return newMap; }); }, (error) => { console.error(`文件 ${file.name} 上传失败:`, error); setUploadingFiles((prev) => { const newMap = new Map(prev); newMap.delete(fileId); return newMap; }); }, ); } catch (error) { console.error(`文件 ${file.name} 上传出错:`, error); } } }; return (
{uploadingFiles.size > 0 && (

正在上传的文件:

{Array.from(uploadingFiles.entries()).map(([fileId, progress]) => (
{fileId}: {progress}%
))}
)}
); } ``` ## 特性 ### 1. 断点续传 TUS 协议支持断点续传,如果上传过程中断,可以从中断的地方继续上传。 ### 2. 大文件支持 适合上传大文件,没有文件大小限制(取决于服务器配置)。 ### 3. 进度跟踪 实时显示上传进度,提供良好的用户体验。 ### 4. 错误处理 提供详细的错误信息和重试机制。 ### 5. 自动重试 内置重试机制,网络异常时自动重试。 ## 故障排除 ### 1. 环境变量获取不到 确保环境变量以 `NEXT_PUBLIC_` 开头,并且 Next.js 应用已重启。 ### 2. 上传失败 检查服务器是否正在运行,端口是否正确。 ### 3. CORS 错误 确保后端服务器配置了正确的 CORS 设置。 ### 4. 文件无法访问 确认文件上传成功后,检查返回的 URL 是否正确。 ## 注意事项 1. **Next.js 环境变量**:客户端组件只能访问 `NEXT_PUBLIC_` 前缀的环境变量 2. **服务器配置**:确保后端服务器支持 TUS 协议 3. **文件大小**:虽然支持大文件,但要注意服务器和客户端的内存限制 4. **网络环境**:在网络不稳定的环境下,断点续传功能特别有用 ## API 路由 Hook 会访问以下 API 路由: - `POST /upload` - TUS 上传端点 - `GET /download/:fileId` - 文件下载/访问 - `GET /api/storage/resource/:fileId` - 获取文件信息 - `HEAD /upload/:fileId` - 获取上传状态