Angular文件上传功能正常,但文件名一段时间后变为随机文本
问题原因
你代码里的核心错误是混淆了文件名存储和文件内容读取的逻辑:
- 一开始你把
this.attachment赋值为文件名,此时页面正常显示文件名 - 但随后调用
reader.readAsDataURL(this.attachment)时,传入的是文件名字符串而非实际的File对象,FileReader会把这个字符串当成内容进行编码 - 当FileReader加载完成(4-5秒后),
reader.result会是该文件名的base64编码值,你又将其赋值给this.attachment,导致页面显示变成乱码一样的base64字符串
修复方案
需要分开存储文件名和文件内容——页面展示用文件名,上传服务器用文件内容(或base64)。
修改后的TS代码
isAttachment: boolean; attachmentFileName: string; // 专门存储文件名,用于页面展示 attachmentContent: string; // 存储文件的base64内容,用于上传服务器 onFileChanged(attachmentInput: any) { if (attachmentInput.target.files && attachmentInput.target.files[0]) { const file = attachmentInput.target.files[0]; // 保存文件名到单独变量 this.attachmentFileName = file.name; // 读取文件内容用于上传 const reader = new FileReader(); reader.onload = (e: any) => { this.attachmentContent = reader.result; // 此处可将this.attachmentContent传给服务器接口 }; // 传入实际的File对象,而非文件名 reader.readAsDataURL(file); } } deleteFile() { this.attachmentFileName = null; this.attachmentContent = null; this.expository.attachment = null; this.isAttachment = false; }
修改后的HTML代码
将原显示{{attachment}}的地方替换为{{attachmentFileName}},其余逻辑对应调整:
<div *ngIf="expository.isAttachment == true"> <div [hidden]="expository.id"> <div *ngIf="attachmentFileName" class="row container-fluid "> <input #attachmentInput type="file" (change)="onFileChanged($event)" class="fileInputProfile " accept=".pdf" #fileInput id="file"/> </div> </div> <div *ngIf="!attachmentFileName" class="row container-fluid "> <input type="file" (change)="onFileChanged($event)" class="fileInputProfile " accept=".pdf" #fileInput id="file"/> </div> <div class="img-space"> <div *ngIf="attachmentFileName"> <div style="margin-bottom: 5%;"> <mat-icon>article</mat-icon> {{attachmentFileName}} </div> <button type="button" class="btn btn-danger " (click)="deleteFile()" > Remove </button> </div> </div> </div>
额外优化建议
如果仅需上传文件到服务器,无需用FileReader转base64,直接用FormData提交更高效:
onFileChanged(attachmentInput: any) { if (attachmentInput.target.files && attachmentInput.target.files[0]) { const file = attachmentInput.target.files[0]; this.attachmentFileName = file.name; // 用FormData封装文件 const formData = new FormData(); formData.append('attachment', file); // 调用HTTP服务提交,示例: // this.http.post('/api/upload', formData).subscribe(res => { ... }); } }
内容的提问来源于stack exchange,提问作者hamza muzafar
相关产品推荐
相关产品推荐

