Angular 17自定义Observable实现文件上传验证遇阻
解决Angular 17中文件MIME类型验证的两个问题
问题1:Observable.create 废弃替代
你已经用 new Observable() 替代了废弃的 Observable.create(),这是正确的做法——RxJS 现在推荐直接使用 Observable 构造函数来创建自定义流,不用再纠结废弃的 API 了。
问题2:null 类型不匹配
原来的返回类型和 Observer 类型只允许 { [key: string]: any } 类型的值,但验证通过时我们需要返回 null(表示没有验证错误),所以需要把类型扩展为包含 null 的联合类型。
修改后的完整代码
import { AbstractControl } from '@angular/forms'; import { Observable, Observer } from 'rxjs'; export const mimeType = ( control: AbstractControl ): Promise<{ [key: string]: any } | null> | Observable<{ [key: string]: any } | null> => { const file = control.value as File; const filereader = new FileReader(); // 调整Observer类型,允许null值 return new Observable((observer: Observer<{ [key: string]: any } | null>) => { // 处理文件读取完成事件 const onLoadEnd = () => { const arr = new Uint8Array(filereader.result as ArrayBuffer).subarray(0, 4); let header = ''; let isValid = false; for (let i = 0; i < arr.length; i++) { header += arr[i].toString(16); } // 修正PNG头(原代码少了最后一位7,可选调整) switch (header) { case '89504e47': isValid = true; break; case 'ffd8ffe0': case 'ffd8ffe1': case 'ffd8ffe2': case 'ffd8ffe3': case 'ffd8ffe8': isValid = true; break; default: isValid = false; break; } if (isValid) { observer.next(null); } else { observer.next({ invalidMimeType: true }); } observer.complete(); }; // 处理文件读取错误 const onError = () => { observer.error('文件读取失败'); observer.complete(); }; filereader.addEventListener('loadend', onLoadEnd); filereader.addEventListener('error', onError); filereader.readAsArrayBuffer(file); // 返回清理函数,移除事件监听避免内存泄漏 return () => { filereader.removeEventListener('loadend', onLoadEnd); filereader.removeEventListener('error', onError); }; }); };
关键修改点说明
- 类型调整:把返回类型和 Observer 类型都改成
{ [key: string]: any } | null,这样observer.next(null)就符合类型要求了。 - 错误处理:新增了
error事件监听,避免文件读取失败时流一直处于挂起状态。 - 内存泄漏防护:添加了清理函数,在 Observable 取消订阅时移除 FileReader 的事件监听,这是自定义 Observable 的最佳实践。
- 可选修正:原代码中 PNG 文件头写的是
'89504E4',正确的 PNG 文件头应该是'89504e47'(对应十六进制的89 50 4E 47),建议修正这个小问题以确保PNG文件验证准确。
内容的提问来源于stack exchange,提问作者Zayno lane
相关产品推荐
相关产品推荐

