假设有一个接口返回excel文件,我们前段需要请求这个接口获得这个文件,然后保存到本地,达到下载的效果。
首先我们是需要去调用这个接口的,接口返回的body里面是一个excel文件。
在Angular中使用HttpClient处理的GET/POST请求都是json数据格式的处理,那文件响应如何处理?
1 | get( |
在Angular中有15重重载:
observe: 'body';,responseType: 'arraybuffer';return Observable<ArrayBuffer>。observe: 'body';,responseType: 'blob';return Observable<Blob>。observe: 'body';,responseType: 'text';return Observable<string>。observe: 'body';,responseType: 'json';return Observable<Object>。observe: 'body';,responseType: 'json';return Observable<T>。observe: 'events';,responseType: 'arraybuffer';return Observable<ArrayBuffer>。observe: 'events';,responseType: 'blob';return Observable<Blob>。observe: 'events';,responseType: 'text';return Observable<string>。observe: 'events';,responseType: 'json';return Observable<HttpEvent<Object>>。observe: 'events';,responseType: 'json';return Observable<HttpEvent<T>>。observe: 'response';,responseType: 'arraybuffer';return Observable<HttpResponse<ArrayBuffer>>。observe: 'response';,responseType: 'blob';return Observable<HttpResponse<Blob>>。observe: 'response';,responseType: 'text';return Observable<HttpResponse<string>>。observe: 'response';,responseType: 'json';return Observable<HttpResponse<Object>>。observe: 'response';,responseType: 'json';return Observable<HttpResponse<T>>。
发现正好有我们需要的重载,我们需要监听response,并且返回的body里面是Blob,那么我们可以这样发起一个请求:
1 | export class TestComponent implements OnInit { |
这里需要看下HttpResponse, 它有个属性type:
Sent = 0请求通过网络发送UploadProgress = 1接收到上传事件ResponseHeader = 2接收到响应状态码和标头DownloadProgress = 3收到下载进度事件Response = 4收到body在内的所有响应User = 5来自拦截器或后端的自定义事件(哦哟,这个好像很有意思🤔)
也就是说我们监测到HttpResponse.type === 4的时候才可以去处理响应里面的Blob:
1 | this._http.post(url, params, { |
处理下载
HTML中的<a>标签我们一般来用于导航,但它有一个很有用的属性download。这个属性指示浏览器下载URL而不是导航到它,因此将提示用户将其保存为本地文件。如果download属性有一个值,那么这个值将在下载保存过程中作为预填充的文件名(如果用户需要,仍然可以修改保存的文件名)。此属性对允许的值没有限制,但是/和\会被转换为下划线。大多数文件系统限制了文件中的标点符号,故此,浏览器将响应的调整建议的文件名。参考MDN 标签。
需要注意的是,这个熟悉仅适用于同源URL。当然我们可以使用blob: URL和data: URL以方便用户下载使用JavaScript生成的内容(比如使用canvas生成的图片等)。
如果HTTP响应头信息中有属性Content-Diposition设置了文件名,那么浏览器会优先使用此属性。
那我们可以来完成下载逻辑:
1 | const objUrl = window.URL.createObjectURL(res.body); |
最终代码:
1 | export class TestComponent implements OnInit { |
梳理代码,也是整理和排查不清楚的地方。