ng2-file-upload:如何避免使用FormData,以原始数据上传文件?
解决方案:绕开ng2-file-upload的FormData上传逻辑
ng2-file-upload本身没有提供禁用FormData的配置项,因为它的核心上传逻辑就是基于FormData设计的。要实现直接发送文件原始数据到S3预签名URL,你有两种可行方案:
方案1:直接使用原生XMLHttpRequest处理上传
如果你不需要依赖ng2-file-upload的文件管理逻辑,直接用原生XHR是最简洁的方式:
// 假设已获取S3预签名URL和用户选择的File对象 const presignedUrl = "你的S3预签名PUT URL"; const targetFile: File = 选中的文件实例; const xhr = new XMLHttpRequest(); xhr.open("PUT", presignedUrl, true); // 关键:设置与预签名URL生成时一致的Content-Type // 如果生成签名时指定了固定类型,这里要严格匹配;否则用文件自身的type或默认值 xhr.setRequestHeader("Content-Type", targetFile.type || "application/octet-stream"); // 监听上传状态 xhr.onload = () => { if (xhr.status === 200) { console.log("文件上传成功"); // 这里可以添加成功后的业务逻辑 } else { console.error("上传失败:", xhr.responseText); } }; xhr.onerror = () => { console.error("上传请求发生错误"); }; // 直接发送文件原始数据,无需包装FormData xhr.send(targetFile);
方案2:扩展ng2-file-upload的FileUploader类
如果想保留ng2-file-upload的文件选择、队列管理等功能,只需重写它的uploadItem方法,替换掉FormData上传逻辑:
import { FileUploader, FileItem } from "ng2-file-upload"; // 自定义上传器,重写核心上传方法 class S3RawFileUploader extends FileUploader { // 重写上传逻辑,跳过FormData uploadItem(item: FileItem): void { // 替换为你的预签名URL获取逻辑(比如从后端接口请求) const presignedUrl = this.getPresignedUrl(item); const xhr = new XMLHttpRequest(); xhr.open("PUT", presignedUrl, true); xhr.setRequestHeader("Content-Type", item.file.type || "application/octet-stream"); // 关联ng2-file-upload的回调事件 xhr.onload = () => { if (xhr.status === 200) { item.onSuccess(xhr.responseText, xhr.status, xhr); this.onSuccessItem(item, xhr.responseText, xhr.status, xhr); } else { item.onError(xhr.responseText, xhr.status, xhr); this.onErrorItem(item, xhr.responseText, xhr.status, xhr); } }; xhr.onerror = () => { item.onError("网络请求错误", xhr.status, xhr); this.onErrorItem(item, "网络请求错误", xhr.status, xhr); }; xhr.send(item.file); } // 自定义方法:根据文件信息获取S3预签名URL private getPresignedUrl(item: FileItem): string { // 这里实现你的预签名URL获取逻辑,比如: // 1. 提前为所有文件请求好签名并存储 // 2. 实时调用后端接口生成签名 return "生成好的S3预签名PUT URL"; } } // 在组件中使用自定义上传器 this.uploader = new S3RawFileUploader({ url: "placeholder", // 这里的URL会被重写,随便填即可 autoUpload: true // 根据需求设置是否自动上传 });
注意事项
- S3预签名URL对请求参数有严格校验:请求方法(必须是PUT,和生成签名时一致)、Content-Type必须完全匹配,否则会返回签名错误。
- 如果你的预签名URL包含其他签名参数(比如
x-amz-acl),需要在XHR请求头中添加对应的字段。
内容的提问来源于stack exchange,提问作者Hemal Gondaliya
相关产品推荐
相关产品推荐

