Angular - 使用 HttpClient API 下载 zip 存档失败
Angular - Downloading a zip archive using HttpClient API fails
在我们的 Angular5 网络应用程序中,我们调用 API 来获取 zip 存档(后端是使用 SharpZipLib 的 ASP.NET Core 2.1)。它使用 Angular 的旧 HTTP API 工作正常:)
但是由于我们升级到新的 HttpClient API(使用 HttpInterceptor 处理 XSRF),现在下载失败且没有任何解释(API 的响应是 200 OK)
这是实际代码:
public getCsvArchive(url: string) {
const headers = new HttpHeaders({ 'responseType': 'arraybuffer' });
return this._http.get(url, { headers } )
.timeout(ServiceConfigurator.TIMEOUT)
.catch(this.handleError);
}
出于某些原因,如果我直接将 "responseType: arraybuffer" 放入 get 方法中,下载工作正常....但检索到的文件的大小不是我们预期的(存档甚至无法打开)
也许拦截器是罪魁祸首?
@Injectable()
export class RequestInterceptor implements HttpInterceptor {
private getTokenName = 'XSRF-TOKEN';
private setTokenName = 'X-XSRF-TOKEN';
private tokenValue: string;
constructor(private _cookieService: CookieService) { }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
let headers = new HttpHeaders({
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
'Cache-Control': 'no-cache',
'if-none-match': 'no-match-for-this',
'Pragma': 'no-cache'
});
if (req.method !== 'GET') {
if (this.tokenValue) {
headers = headers.append(this.setTokenName, this.tokenValue);
}
return next.handle(req.clone({ headers }));
} else {
return next.handle(req.clone({ headers })).do((ev: HttpEvent<any>) => {
if (ev instanceof HttpResponse) {
if (environment.use_dp) {
console.log(this._cookieService.get(this.getTokenName));
this.tokenValue = this._cookieService.get(this.getTokenName);
}
this._cookieService.put(this.getTokenName, this.tokenValue);
}
});
}
}
}
尝试这样的事情:
使用 blob:
服务调用:
this.type = 'application/zip'
getFile(url:string,type:string){
let headers = new HttpHeaders().append("Authorization", "Bearer " + token)
return this.httpClient.get(url, {responseType: 'arraybuffer',headers:headers});
}
分量:
从服务器获取文件:
getFile() {
this.fileService.getFile('url, this.type).subscribe(respData => {
this.downLoadFile(respData, this.type);
}, error => {
console.log(error);
});
}
下载文件:
* Method is use to download file.
* @param data - Array Buffer data
* @param type - type of the document.
*/
downLoadFile(data: any, type: string) {
var blob = new Blob([data], { type: type.toString() });
var url = window.URL.createObjectURL(blob);
var pwa = window.open(url);
if (!pwa || pwa.closed || typeof pwa.closed == 'undefined') {
alert('Please disable your Pop-up blocker and try again.');
}
}
好吧,我发现了问题所在,但我忘了包含另一段代码,所以我将以 UnluckyAj 响应为例,因为它非常相似;)
这是我在迁移到新的 HttpClient 之前所拥有的 API
getFile() {
this.fileService.getFile('url', this.type).subscribe(respData => {
this.downloadFile(respData._body, this.type);
}, error => {
console.log(error);
});
}
此时 'respData' 是一个特殊的对象,它有一个名为“_body”的 属性,其中包含我感兴趣的全部内容:)
但是在移动到 HttpClient 之后,'respData' 已经是一个 'Blob' 并且没有像以前那样的 '_body' 属性。因此,通过将代码更改为与 UnluckyAj (+1) 相同的代码:
getFile() {
this.fileService.getFile('url', this.type).subscribe(respData => {
this.downloadFile(respData., this.type);
}, error => {
console.log(error);
});
}
它现在可以工作了 :) 但是在 downloadFile 方法中我使用了 FileSaver 库,因为我们的 webapp 不是 Progressive WebApp ;)
downloadFile(data: any) {
const blob = new Blob([data], { type: 'application/zip' });
const fileName = 'CSV_CONTENT.ZIP';
FileSaver.saveAs(blob, fileName);
}
在我们的 Angular5 网络应用程序中,我们调用 API 来获取 zip 存档(后端是使用 SharpZipLib 的 ASP.NET Core 2.1)。它使用 Angular 的旧 HTTP API 工作正常:)
但是由于我们升级到新的 HttpClient API(使用 HttpInterceptor 处理 XSRF),现在下载失败且没有任何解释(API 的响应是 200 OK)
这是实际代码:
public getCsvArchive(url: string) {
const headers = new HttpHeaders({ 'responseType': 'arraybuffer' });
return this._http.get(url, { headers } )
.timeout(ServiceConfigurator.TIMEOUT)
.catch(this.handleError);
}
出于某些原因,如果我直接将 "responseType: arraybuffer" 放入 get 方法中,下载工作正常....但检索到的文件的大小不是我们预期的(存档甚至无法打开)
也许拦截器是罪魁祸首?
@Injectable()
export class RequestInterceptor implements HttpInterceptor {
private getTokenName = 'XSRF-TOKEN';
private setTokenName = 'X-XSRF-TOKEN';
private tokenValue: string;
constructor(private _cookieService: CookieService) { }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
let headers = new HttpHeaders({
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
'Cache-Control': 'no-cache',
'if-none-match': 'no-match-for-this',
'Pragma': 'no-cache'
});
if (req.method !== 'GET') {
if (this.tokenValue) {
headers = headers.append(this.setTokenName, this.tokenValue);
}
return next.handle(req.clone({ headers }));
} else {
return next.handle(req.clone({ headers })).do((ev: HttpEvent<any>) => {
if (ev instanceof HttpResponse) {
if (environment.use_dp) {
console.log(this._cookieService.get(this.getTokenName));
this.tokenValue = this._cookieService.get(this.getTokenName);
}
this._cookieService.put(this.getTokenName, this.tokenValue);
}
});
}
}
}
尝试这样的事情:
使用 blob:
服务调用:
this.type = 'application/zip'
getFile(url:string,type:string){
let headers = new HttpHeaders().append("Authorization", "Bearer " + token)
return this.httpClient.get(url, {responseType: 'arraybuffer',headers:headers});
}
分量:
从服务器获取文件:
getFile() {
this.fileService.getFile('url, this.type).subscribe(respData => {
this.downLoadFile(respData, this.type);
}, error => {
console.log(error);
});
}
下载文件:
* Method is use to download file.
* @param data - Array Buffer data
* @param type - type of the document.
*/
downLoadFile(data: any, type: string) {
var blob = new Blob([data], { type: type.toString() });
var url = window.URL.createObjectURL(blob);
var pwa = window.open(url);
if (!pwa || pwa.closed || typeof pwa.closed == 'undefined') {
alert('Please disable your Pop-up blocker and try again.');
}
}
好吧,我发现了问题所在,但我忘了包含另一段代码,所以我将以 UnluckyAj 响应为例,因为它非常相似;)
这是我在迁移到新的 HttpClient 之前所拥有的 API
getFile() {
this.fileService.getFile('url', this.type).subscribe(respData => {
this.downloadFile(respData._body, this.type);
}, error => {
console.log(error);
});
}
此时 'respData' 是一个特殊的对象,它有一个名为“_body”的 属性,其中包含我感兴趣的全部内容:)
但是在移动到 HttpClient 之后,'respData' 已经是一个 'Blob' 并且没有像以前那样的 '_body' 属性。因此,通过将代码更改为与 UnluckyAj (+1) 相同的代码:
getFile() {
this.fileService.getFile('url', this.type).subscribe(respData => {
this.downloadFile(respData., this.type);
}, error => {
console.log(error);
});
}
它现在可以工作了 :) 但是在 downloadFile 方法中我使用了 FileSaver 库,因为我们的 webapp 不是 Progressive WebApp ;)
downloadFile(data: any) {
const blob = new Blob([data], { type: 'application/zip' });
const fileName = 'CSV_CONTENT.ZIP';
FileSaver.saveAs(blob, fileName);
}