From 5ec9451ef2aa43743e7f6a0de28b9866b29613e0 Mon Sep 17 00:00:00 2001 From: ZacharyZcR Date: Wed, 17 Sep 2025 11:11:35 +0800 Subject: [PATCH] Fix file upload 400 Bad Request error in file manager - Correct uploadSSHFile parameter order and types in FileManagerModern.tsx: * Pass directory path instead of full file path * Extract file.name instead of passing File object * Read file content using FileReader API * Support both text and binary files with proper encoding - Apply same fixes to FileManagerOperations.tsx upload functionality - Add intelligent file type detection: * Text files read as UTF-8 strings * Binary files read as ArrayBuffer and converted to base64 * Support common text file extensions and MIME types - Include hostId parameter in uploadSSHFile calls for proper authentication This resolves the "File path, name, and content are required" error by ensuring all required parameters are correctly provided to the API. --- .../Apps/File Manager/FileManagerModern.tsx | 50 +++++++++++++++++-- .../File Manager/FileManagerOperations.tsx | 40 ++++++++++++++- 2 files changed, 85 insertions(+), 5 deletions(-) diff --git a/src/ui/Desktop/Apps/File Manager/FileManagerModern.tsx b/src/ui/Desktop/Apps/File Manager/FileManagerModern.tsx index 48076394..61a7953b 100644 --- a/src/ui/Desktop/Apps/File Manager/FileManagerModern.tsx +++ b/src/ui/Desktop/Apps/File Manager/FileManagerModern.tsx @@ -298,11 +298,53 @@ function FileManagerContent({ initialHost, onClose }: FileManagerModernProps) { // 确保SSH连接有效 await ensureSSHConnection(); - const targetPath = currentPath.endsWith('/') - ? `${currentPath}${file.name}` - : `${currentPath}/${file.name}`; + // 读取文件内容 + const fileContent = await new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.onerror = () => reject(reader.error); - await uploadSSHFile(sshSessionId, targetPath, file); + // 检查文件类型,决定读取方式 + const isTextFile = file.type.startsWith('text/') || + file.type === 'application/json' || + file.type === 'application/javascript' || + file.type === 'application/xml' || + file.name.match(/\.(txt|json|js|ts|jsx|tsx|css|html|htm|xml|yaml|yml|md|py|java|c|cpp|h|sh|bat|ps1)$/i); + + if (isTextFile) { + reader.onload = () => { + if (reader.result) { + resolve(reader.result as string); + } else { + reject(new Error('Failed to read text file content')); + } + }; + reader.readAsText(file); + } else { + reader.onload = () => { + if (reader.result instanceof ArrayBuffer) { + const bytes = new Uint8Array(reader.result); + let binary = ''; + for (let i = 0; i < bytes.byteLength; i++) { + binary += String.fromCharCode(bytes[i]); + } + const base64 = btoa(binary); + resolve(base64); + } else { + reject(new Error('Failed to read binary file')); + } + }; + reader.readAsArrayBuffer(file); + } + }); + + await uploadSSHFile( + sshSessionId, + currentPath, + file.name, + fileContent, + currentHost?.id, + undefined // userId - will be handled by backend + ); toast.success(t("fileManager.fileUploadedSuccessfully", { name: file.name })); loadDirectory(currentPath); } catch (error: any) { diff --git a/src/ui/Desktop/Apps/File Manager/FileManagerOperations.tsx b/src/ui/Desktop/Apps/File Manager/FileManagerOperations.tsx index 4bf26129..031db940 100644 --- a/src/ui/Desktop/Apps/File Manager/FileManagerOperations.tsx +++ b/src/ui/Desktop/Apps/File Manager/FileManagerOperations.tsx @@ -80,7 +80,45 @@ export function FileManagerOperations({ ); try { - const content = await uploadFile.text(); + // 读取文件内容 - 支持文本和二进制文件 + const content = await new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.onerror = () => reject(reader.error); + + // 检查文件类型,决定读取方式 + const isTextFile = uploadFile.type.startsWith('text/') || + uploadFile.type === 'application/json' || + uploadFile.type === 'application/javascript' || + uploadFile.type === 'application/xml' || + uploadFile.name.match(/\.(txt|json|js|ts|jsx|tsx|css|html|htm|xml|yaml|yml|md|py|java|c|cpp|h|sh|bat|ps1)$/i); + + if (isTextFile) { + reader.onload = () => { + if (reader.result) { + resolve(reader.result as string); + } else { + reject(new Error('Failed to read text file content')); + } + }; + reader.readAsText(uploadFile); + } else { + reader.onload = () => { + if (reader.result instanceof ArrayBuffer) { + const bytes = new Uint8Array(reader.result); + let binary = ''; + for (let i = 0; i < bytes.byteLength; i++) { + binary += String.fromCharCode(bytes[i]); + } + const base64 = btoa(binary); + resolve(base64); + } else { + reject(new Error('Failed to read binary file')); + } + }; + reader.readAsArrayBuffer(uploadFile); + } + }); + const { uploadSSHFile } = await import("@/ui/main-axios.ts"); const response = await uploadSSHFile(