如何在 Angular 中使用浏览器的本机下载小部件以编程方式下载文件?
How do I programmatically download a file using the browser's native download widget in Angular?
所以,当我请求我的网络服务下载一个 zip 文件时,它会偷偷下载文件内容,突然间,该文件出现在下载任务栏中但已经下载完整 (100%)
使用以下 angular 方法:
const endpoint = "http://localhost:8080/download/zip"
this.http.get<Blop>(endpoint, {headers: httpHeaders, responseType: 'blob', reportProgress: true })
我是这样订阅的:
this.http.get<Blop>(endpoint, {headers: httpHeaders, responseType: 'blob', reportProgress: true }).subscribe({
next: data => {
console.log('blocking or not');
const blob = new Blob([data as any], { type: 'application/zip' });
window.location.href = URL.createObjectURL(blob);
}
})
所以我注意到我的 console.log(...)
直到下载结束才被调用,所以我想浏览器-ui 在下载到达 [=15= 之前无法检测到下载].
如何强制下载结束前显示在下载任务栏,并在浏览器中查看下载进度?我找不到与异步 blop 或类似内容相关的任何内容。
PS:我的后端正在处理数据流,所以后端不是问题。通过浏览器直接调用我的api时,我们可以在下载任务栏看到下载进度。不过,如果你们有兴趣,这是片段 (spring-boot)
@GetMapping("/download/zip")
fun download(response: HttpServletResponse): StreamingResponseBody {
val file = downloads.download("launcher")
response.contentType = "application/zip"
response.setHeader(
"Content-Disposition",
"attachment;filename=sample.zip"
)
response.setContentLengthLong(file.length())
return StreamingResponseBody { outputStream: OutputStream ->
var bytesRead: Int
val buffer = ByteArray(2048)
val inputStream: InputStream = file.inputStream()
while (inputStream.read(buffer).also { bytesRead = it } != -1) {
outputStream.write(buffer, 0, bytesRead)
}
}
}
假设您使用的是 Angular 的 HttpClient
,像这样的东西应该可以工作:
const endpoint = "http://localhost:8080/download/zip"
const req = new HttpRequest('GET', endpoint, { reportProgress: true, })
this.Http.request(req).subscribe(event => {
if (event.type === HttpEventType.DownloadProgress) {
const percentDone = Math.round(100 * event.loaded / (event.total || 0))
console.log(percentDone);
} else if (event instanceof HttpResponse) {
const blob = new Blob([event.body as any], { type: 'application/zip' });
window.location.href = URL.createObjectURL(blob);
}
})
下载有两种方式:
- http.get + msSaveOrOpenBlob(如果已定义)/createObjectURL
- 您可以完全控制请求、流程和错误。例如。你可以取消请求,添加额外的headers,等等
- 下载仍在您的应用程序流程中,例如F5 将取消它。
- 创建隐藏下载 link 并以编程方式单击它
- 你不能添加headers,你不能以简单的方式显示progress/errors(有一些技巧涉及额外的cookies由BE设置)
- 它被描述为单独的过程,例如你可以关闭你的应用程序选项卡或其他任何东西。
似乎没有机会混合使用这两种方法,总的来说,我会说第一种更现代,更适合小文件,但是如果您对它不满意,请尝试第二种 (https://whosebug.com/a/49917066/4019404 ):
function download(url) {
const a = document.createElement('a')
a.href = url
a.download = url.split('/').pop()
document.body.appendChild(a)
a.click()
document.body.removeChild(a)
}
你可以简单地使用这个包
npm i ngx-filesaver
和
constructor(private _http: Http, private _FileSaverService: FileSaverService) {
}
onSave() {
this._http.get('yourfile.png', {
responseType: ResponseContentType.Blob // This must be a Blob type
}).subscribe(res => {
this._FileSaverService.save((<any>res)._body, fileName);
});
}
在此处完成文档 ngx file saver
还有 file saver.js
从技术角度来看,您无法更改浏览器在后台接收文件的行为方式。相反,您可以通过在发出 HTTP 请求时将选项 observe
设置为 events
来 计算下载进度 。这样,您不仅会收到请求的最终响应主体,还会访问中间 HTTP 事件。
之后,您可以在浏览器之外显示自己的下载进度。
Angular 中有多种 HTTP 事件,全部合并到 HttpEvent. We also need to explicitly pass the option reportProgress
in order to receive HttpProgressEvents 类型下。 HTTP 请求最终将如下所示:
this.http.get(url, {
reportProgress: true,
observe: 'events',
responseType: 'blob'
})
您可以在 angular file download progress 找到一个很好的实现。
试试这个:
$('a#someID').attr({target: '_blank',
href : 'http://localhost/directory/file.pdf'});
它使用jQuery
用户包https://www.npmjs.com/package/file-saver
npm i file-saver
然后在您的组件中,导入 SaveAs 方法
import { saveAs } from 'file-saver';
saveAs(url, name);
所以,当我请求我的网络服务下载一个 zip 文件时,它会偷偷下载文件内容,突然间,该文件出现在下载任务栏中但已经下载完整 (100%)
使用以下 angular 方法:
const endpoint = "http://localhost:8080/download/zip"
this.http.get<Blop>(endpoint, {headers: httpHeaders, responseType: 'blob', reportProgress: true })
我是这样订阅的:
this.http.get<Blop>(endpoint, {headers: httpHeaders, responseType: 'blob', reportProgress: true }).subscribe({
next: data => {
console.log('blocking or not');
const blob = new Blob([data as any], { type: 'application/zip' });
window.location.href = URL.createObjectURL(blob);
}
})
所以我注意到我的 console.log(...)
直到下载结束才被调用,所以我想浏览器-ui 在下载到达 [=15= 之前无法检测到下载].
如何强制下载结束前显示在下载任务栏,并在浏览器中查看下载进度?我找不到与异步 blop 或类似内容相关的任何内容。
PS:我的后端正在处理数据流,所以后端不是问题。通过浏览器直接调用我的api时,我们可以在下载任务栏看到下载进度。不过,如果你们有兴趣,这是片段 (spring-boot)
@GetMapping("/download/zip")
fun download(response: HttpServletResponse): StreamingResponseBody {
val file = downloads.download("launcher")
response.contentType = "application/zip"
response.setHeader(
"Content-Disposition",
"attachment;filename=sample.zip"
)
response.setContentLengthLong(file.length())
return StreamingResponseBody { outputStream: OutputStream ->
var bytesRead: Int
val buffer = ByteArray(2048)
val inputStream: InputStream = file.inputStream()
while (inputStream.read(buffer).also { bytesRead = it } != -1) {
outputStream.write(buffer, 0, bytesRead)
}
}
}
假设您使用的是 Angular 的 HttpClient
,像这样的东西应该可以工作:
const endpoint = "http://localhost:8080/download/zip"
const req = new HttpRequest('GET', endpoint, { reportProgress: true, })
this.Http.request(req).subscribe(event => {
if (event.type === HttpEventType.DownloadProgress) {
const percentDone = Math.round(100 * event.loaded / (event.total || 0))
console.log(percentDone);
} else if (event instanceof HttpResponse) {
const blob = new Blob([event.body as any], { type: 'application/zip' });
window.location.href = URL.createObjectURL(blob);
}
})
下载有两种方式:
- http.get + msSaveOrOpenBlob(如果已定义)/createObjectURL
- 您可以完全控制请求、流程和错误。例如。你可以取消请求,添加额外的headers,等等
- 下载仍在您的应用程序流程中,例如F5 将取消它。
- 创建隐藏下载 link 并以编程方式单击它
- 你不能添加headers,你不能以简单的方式显示progress/errors(有一些技巧涉及额外的cookies由BE设置)
- 它被描述为单独的过程,例如你可以关闭你的应用程序选项卡或其他任何东西。
似乎没有机会混合使用这两种方法,总的来说,我会说第一种更现代,更适合小文件,但是如果您对它不满意,请尝试第二种 (https://whosebug.com/a/49917066/4019404 ):
function download(url) {
const a = document.createElement('a')
a.href = url
a.download = url.split('/').pop()
document.body.appendChild(a)
a.click()
document.body.removeChild(a)
}
你可以简单地使用这个包
npm i ngx-filesaver
和
constructor(private _http: Http, private _FileSaverService: FileSaverService) {
}
onSave() {
this._http.get('yourfile.png', {
responseType: ResponseContentType.Blob // This must be a Blob type
}).subscribe(res => {
this._FileSaverService.save((<any>res)._body, fileName);
});
}
在此处完成文档 ngx file saver 还有 file saver.js
从技术角度来看,您无法更改浏览器在后台接收文件的行为方式。相反,您可以通过在发出 HTTP 请求时将选项 observe
设置为 events
来 计算下载进度 。这样,您不仅会收到请求的最终响应主体,还会访问中间 HTTP 事件。
之后,您可以在浏览器之外显示自己的下载进度。
Angular 中有多种 HTTP 事件,全部合并到 HttpEvent. We also need to explicitly pass the option reportProgress
in order to receive HttpProgressEvents 类型下。 HTTP 请求最终将如下所示:
this.http.get(url, {
reportProgress: true,
observe: 'events',
responseType: 'blob'
})
您可以在 angular file download progress 找到一个很好的实现。
试试这个:
$('a#someID').attr({target: '_blank',
href : 'http://localhost/directory/file.pdf'});
它使用jQuery
用户包https://www.npmjs.com/package/file-saver
npm i file-saver
然后在您的组件中,导入 SaveAs 方法
import { saveAs } from 'file-saver';
saveAs(url, name);