Angular 2文件下载异常:文件始终为XML格式且Windows无法打开
解决下载文件始终为XML格式且Windows无法打开的问题
看起来你遇到的核心问题是:调用REST接口下载文件时,无论原文件是什么格式,最终保存的都是XML文件,而且Windows系统里还打不开。我仔细看了你的代码,问题大概率出在请求头配置和响应内容的处理上,下面给你一步步分析和解决:
问题分析
- 请求头设置错误:你在请求里强制设置了
"Content-Type": "application/x-www-form-urlencoded",但下载文件场景下,这个头是用来告诉服务端你发送的请求体格式,而我们需要的是让服务端返回正确的文件类型,应该用Accept头来声明接收任意类型的响应。 - 服务端响应可能异常:如果服务端返回的不是文件二进制数据,而是XML格式的错误信息(比如参数错误、权限问题),那你拿到的Blob自然是XML内容;另外如果服务端没有正确设置
Content-Type响应头,浏览器会默认按XML解析。
修改后的代码示例
1. 调整服务端请求方法(myservice)
downloadFile(ao_id: string, id: string): Observable<Blob> { // 替换Content-Type为Accept,允许接收任意类型响应 const cpHeaders = new Headers({ "Accept": "*/*" }); let cpParams: URLSearchParams = new URLSearchParams(); cpParams.set("ao_id", ao_id); cpParams.set("type", id); const options = new RequestOptions({ headers: cpHeaders, search: cpParams, responseType: ResponseContentType.Blob // 保留这个,确保返回Blob类型 }); return this.http .get(this.downloadUrl, options) .map(res => { // 打印响应头的Content-Type,确认服务端返回的文件类型是否正确 console.log("服务端返回的Content-Type:", res.headers.get("Content-Type")); return res.blob(); }) .catch(this.handleError); }
2. 优化前端订阅逻辑(获取正确文件名)
如果服务端返回了Content-Disposition响应头,我们可以从中解析出正确的文件名和格式,避免手动设置的this.fileName格式不匹配:
downloading() { this.route.params .switchMap((params: Params) => this.service.downloadFile(params["ao_id"], params["id"]) ) .subscribe(blob => { let fileName = this.fileName; // 从响应头解析服务端返回的文件名(如果有) const contentDisposition = this.service.http.getResponseHeader("Content-Disposition"); if (contentDisposition) { const fileNameMatch = contentDisposition.match(/filename="?([^"]+)"?/); if (fileNameMatch && fileNameMatch.length > 1) { fileName = fileNameMatch[1]; } } importedSaveAs(blob, fileName); const fileURL = URL.createObjectURL(blob); window.open(fileURL); }); }
额外排查步骤
- 先用Postman调用这个下载接口,确认返回的是正确的文件二进制数据,同时检查响应头的
Content-Type是否和文件类型匹配(比如PDF是application/pdf,图片是image/png)。 - 如果下载的文件用文本编辑器打开是XML内容,说明服务端返回的是错误信息,需要先排查接口逻辑是否正确处理了你的参数。
内容的提问来源于stack exchange,提问作者assia
相关产品推荐
相关产品推荐

