jimmywarting / StreamSaver.js

StreamSaver writes stream to the filesystem directly asynchronous
https://jimmywarting.github.io/StreamSaver.js/example.html
MIT License
4.04k stars 418 forks source link

How to download large files using streamsaver with angular's HttpClient #155

Closed ramdp closed 4 years ago

ramdp commented 4 years ago

@jimmywarting Hi, I am using angular9 HttpClient and .net core api. Can you help me how to download large file if I don't want to use fetch api?

jimmywarting commented 4 years ago

First and foremost, if the file is coming from a server (.net application) try to solve it using server technics first before trying to emulate what a server is doing together StreamSaver

StreamSaver installs a service worker and intercepts requests like some man in the middle and dose what the server have done for years. streamsaver and filesaver alike is mostly meant for client generated content.


I'm no expert at angular but I'm 99% certain that you can't use angulars HttpClient due to the fact that angular uses XMLHttpRequest? the old xhr isn't streamable so you have to download everything first before you can start saving stuff which kinda break the purpose of using streamsaver. You have to get a ReadableStream from the the Response.prototype.body object which angular dose not have. so you can't pipe data to the disk


my recommendation:

  1. Solve it using just the server by appending content-disposition attachment headers. and just navigate to that url whether it is with navigation or a <form> submission with other request methods.
  2. If you don't have control over the server, try just using <a href="url" download="file">
  3. use the fetch api and pipe it

The problem you will have is that they might start thinking it's downloading using regular http download since it looks/feels like the native downloader - but in fact the web page can't be closed or reloaded since the ajax request will go throught the main thread.

ramdp commented 4 years ago

Thanks for clarification!

jimmywarting commented 4 years ago

also you maybe can use a own custom HttpBackend that uses fetch - don't know how that works exactly in angular.

ramdp commented 4 years ago

Yes, we are using fetch. My use case is to select multiple files and download as a zip. all files are stored in SQL server. I am not able to zip because for saving multiple files as zip you are instantiating ZIP object I can't find it anywhere. Single files I am able to download easily using fetch. Will exporting createWriter from zip-stream file work? All of the things I am doing in angular component.

jimmywarting commented 4 years ago

The zip part isn't really part of the StreamSaver and isn't exposed in any way. you have to copy the file and use it on your own. https://github.com/jimmywarting/StreamSaver.js/blob/master/examples/zip-stream.js