Angular7+Node.js项目中Safari浏览器无法上传.wav文件 Chrome正常
问题根因
- Safari 对
.wav格式音频的 MIME 类型识别逻辑与 Chrome 不同,默认会将.wav文件识别为audio/x-wav而非通用的audio/wav,你提供的FormData异常截图也能看到该字段差异,如果你的 Node.js 后端或 S3 上传配置做了严格的 MIME 类型校验,就会触发内部服务错误。 - 你的现有代码完全依赖浏览器默认识别的文件类型,没有做兼容处理,且生成的文件名存在小数格式问题,也可能触发部分存储服务的校验规则。
修复方案
1. 前端兼容Safari的MIME类型识别
修改addNewSongService.ts中的trackUpload方法,手动修正wav文件的MIME类型,同时修复文件名生成逻辑:
trackUpload(event, url, duration): Observable<any> { const fileList: FileList = event.target.files; this.tracks = ''; if (fileList.length > 0) { let file: File = fileList[0]; // 统一转小写判断后缀,避免大小写格式的wav文件识别失败 const file_ext = file.name.substr(file.name.lastIndexOf('.') + 1).toLowerCase(); // 修复Safari下wav文件的MIME类型异常问题 if (file_ext === 'wav') { file = new File([file], file.name, { type: 'audio/wav' }); } if ( file.type != 'image/gif' && file.type != 'image/tiff' && file.type != 'image/jpeg' && file.type != 'image/png' ) { const fileName = file.name.split('.').slice(0, -1).join('.'); // 修复时间戳小数问题,避免文件名带小数点触发存储规则校验 this.new_file_name = 'Single_tracks/' + Math.floor(new Date().getTime() / 1000) + '.' + file_ext; const formData: FormData = new FormData(); formData.append('uploadFile', file, this.new_file_name); return this.http .post(url, formData, { // 手动指定Content-Type为undefined,让浏览器自动生成带boundary的正确请求头 headers: { 'Content-Type': 'undefined' } }) .pipe( tap((data) => { this.tracks = { trackName: data['result'].files.uploadFile[0].name, trackLength: duration, fileName: fileName }; this.trackList.next(this.tracks); this.uploadUrl.next(this.tracks); }), catchError((error) => { console.log("trackUpload error==", error); return observableThrowError(error); }) ); } else { return observableThrowError('This file type not supported'); } } return observableThrowError('No file selected'); }
2. 后端校验规则兼容
如果Node.js后端做了文件类型校验,建议同时兼容audio/wav和audio/x-wav两种MIME类型,并且优先通过文件后缀、文件头魔数判断文件类型,不要完全依赖请求携带的MIME类型,避免校验失败和恶意文件上传风险。
内容的提问来源于stack exchange,提问作者Vishnu Jayan
相关产品推荐
相关产品推荐

