You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular中ngFor展示ZIP下载链接时createObjectURL报错求助

Angular生成ZIP下载链接时createObjectURL报错解决方案

问题说明

在Angular应用中实现ZIP文件下载并生成可点击链接,当前代码能完成文件下载打开,但控制台持续报错:

Failed to execute 'createObjectURL' on 'URL': Overload resolution failed

报错触发行:

this.zipFile[0].fileUrl = window.URL.createObjectURL(this.zipFile[0].fileContent);

报错原因

  1. 响应获取方式错误:服务中使用observe: "events",订阅返回的是HttpEvent对象流,而非直接的Blob响应体,value.body可能未正确获取到有效Blob;
  2. 类型不匹配:createObjectURL仅接受Blob/File/MediaSource类型参数,若fileContent不是上述类型(比如为undefined或其他对象),则会触发重载解析失败;
  3. 内存泄漏风险:未及时回收创建的Object URL,长期运行可能导致内存占用过高。

修复方案

1. 调整HTTP请求的观察模式

修改服务代码,将observe改为"body",直接获取Blob响应体:

public downloadFileWithAuthorization(urlOfFile: string, user: string, password: string): Observable<Blob> {
    const headerParams = new HttpHeaders({
        "Content-Type": "application/x-www-form-urlencoded",
        "Authorization": "Basic " + btoa(user + ":" + password),
    });

    return this.http.get(urlOfFile, {
        reportProgress: false,
        observe: "body", // 改为直接获取响应体
        headers: headerParams,
        responseType: "blob"
    });
}

2. 组件中正确处理Blob并添加类型校验

在组件订阅回调中,确保拿到有效Blob后再创建Object URL,并添加类型检查:

getDownloadFile() {
    this.downloadFileSub = this.downloadService.downloadFileWithAuthorization(
        this.emailMessage!.downloadURL![0].path!, 
        this.user, 
        this.password
    ).subscribe({
        next: (blob) => {
            // 校验是否为有效Blob
            if (blob instanceof Blob) {
                this.zipFile[0].fileContent = blob;
                this.zipFile[0].fileUrl = window.URL.createObjectURL(blob);
            }
        },
        error: err => {
            new ErrorMessage(err.message, this.messageService).provide();
        }
    });
}

// 组件销毁时释放Object URL,避免内存泄漏
ngOnDestroy() {
    if (this.zipFile[0]?.fileUrl) {
        window.URL.revokeObjectURL(this.zipFile[0].fileUrl);
    }
    this.downloadFileSub?.unsubscribe();
}

3. 优化HTML链接绑定

使用Angular属性绑定代替插值表达式,避免XSS风险:

<div *ngFor="let urlentity of zipFile">
    <button pButton pRipple icon="p-button-icon pi pi-file-edit" link="true"
            class="p-button-rounded p-button-success mr-2">
        <a [href]="urlentity.fileUrl" target="_blank" rel="noopener noreferrer">{{urlentity.name}}</a>
    </button>
</div>

额外说明

若仍需监听下载进度,可保留observe: "events",但需在回调中判断事件类型为HttpResponse时再获取body:

next: (event) => {
    if (event instanceof HttpResponse && event.body instanceof Blob) {
        this.zipFile[0].fileContent = event.body;
        this.zipFile[0].fileUrl = window.URL.createObjectURL(event.body);
    }
}

内容的提问来源于stack exchange,提问作者DigitalMachine

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 19:25:10