// 使用 fetch 和 FormData 上传文件的示例代码 // 示例 1: 使用 File 对象上传 async function uploadFileUsingFileObject(file: File) { const formData = new FormData(); formData.append('file', file); // 可以添加其他字段 formData.append('filename', file.name); formData.append('description', '文件描述'); formData.append('appKey', 'test'); formData.append('version', '1.0.0'); try { const response = await fetch('http://localhost:51516/client/router', { method: 'POST', body: formData, // 注意:使用 FormData 时不需要手动设置 Content-Type, // 浏览器会自动设置正确的 multipart/form-data 边界 }); if (!response.ok) { throw new Error(`上传失败: ${response.status} ${response.statusText}`); } const result = await response.json(); console.log('上传成功:', result); return result; } catch (error) { console.error('上传出错:', error); throw error; } } // 示例 2: 使用 FileList(如 input[type="file"])上传 async function uploadFilesUsingFileList(files: FileList) { const formData = new FormData(); // 多个文件使用相同的字段名 for (let i = 0; i < files.length; i++) { formData.append('files', files[i]); } try { const response = await fetch('http://localhost:51516/client/router', { method: 'POST', body: formData, }); if (!response.ok) { throw new Error(`上传失败: ${response.status} ${response.statusText}`); } const result = await response.json(); console.log('上传成功:', result); return result; } catch (error) { console.error('上传出错:', error); throw error; } } // 示例 3: 从路径读取文件上传(Node.js 环境,使用 fs 和 Blob) import fs from 'fs'; async function uploadFileFromPath(fileList: string[]) { const formData = new FormData(); for (let m of fileList) { const buffer = fs.readFileSync(m); const file = new File([buffer], m.split('/').pop()!, { type: 'application/octet-stream', }); formData.append('file', file); } formData.append('appKey', 'test'); formData.append('version', '1.0.0'); let token = 'st_n9ycynd4m7wdyw3lejb8plnkyi62uejd'; // 如果需要身份验证,添加令牌 try { const response = await fetch('http://localhost:51516/client/upload' + `?token=${token}`, { method: 'POST', body: formData, }); if (!response.ok) { throw new Error(`上传失败: ${response.status} ${response.statusText}`); } const result = await response.json(); console.log('上传成功:', JSON.stringify(result, null, 2)); return result; } catch (error) { console.error('上传出错:', error); throw error; } } uploadFileFromPath(['./src/test/remote-app.ts', './src/test/upload-file.ts']); // 示例 4: 完整的 HTML 使用示例(浏览器环境) /* // HTML // // async function handleUpload() { const fileInput = document.getElementById('fileInput') as HTMLInputElement; const files = fileInput.files; if (!files || files.length === 0) { alert('请选择文件'); return; } const formData = new FormData(); for (let i = 0; i < files.length; i++) { formData.append('files', files[i]); } // 添加额外数据 formData.append('userId', '12345'); formData.append('timestamp', Date.now().toString()); try { const response = await fetch('http://localhost:51516/client/router', { method: 'POST', body: formData, }); if (!response.ok) { throw new Error(`上传失败: ${response.status}`); } const result = await response.json(); alert('上传成功: ' + JSON.stringify(result)); } catch (error) { alert('上传出错: ' + error); } } */ // 示例 5: 带进度监控的上传(浏览器环境) /* async function uploadWithProgress(file: File, onProgress: (percent: number) => void) { return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); const formData = new FormData(); formData.append('file', file); xhr.upload.addEventListener('progress', (e) => { if (e.lengthComputable) { const percent = (e.loaded / e.total) * 100; onProgress(percent); } }); xhr.addEventListener('load', () => { if (xhr.status === 200) { resolve(JSON.parse(xhr.responseText)); } else { reject(new Error(`上传失败: ${xhr.status}`)); } }); xhr.addEventListener('error', () => reject(new Error('网络错误'))); xhr.addEventListener('abort', () => reject(new Error('上传被取消'))); xhr.open('POST', 'http://localhost:51516/client/router'); xhr.send(formData); }); } // 使用 // const file = fileInput.files[0]; // uploadWithProgress(file, (percent) => { // console.log(`上传进度: ${percent.toFixed(1)}%`); // }).then(result => console.log('完成', result)); */