solution for downloading large files from authenticated endpoint that works across multiple web browsers

I'm currently on the lookout for a solution to download large files (around 2 - 4 GB) from a bearer token protected api endpoint that is compatible with all common browsers including IE 11, Chrome, Firefox, Android Browsers, and Safari. I want it to work seamlessly with angular/ts in browsers only without needing to provide an app.

Challenges with FileSaver

Currently, I am using eligrey/filesaver which consolidates various browser-specific options for client-side blob downloads. This allows me to easily incorporate the bearer token (e.g., with http interceptors).

The issue arises when IE experiences high RAM consumption and freezes at a 1.4GB download.

Issues with StreamSaver

After exploring a more modern approach with StreamSaver.js, I discovered that it only works with chrome and opera, offering direct streaming to disk.

Dilemma with an Unprotected Endpoint

Another common method would involve allowing anonymous access to the download endpoint by requesting a one-time-token first, generating a URL with this token, and prompting the user to download it directly through a new tab opened by the browser and closed immediately upon starting the download.

This technique requires 2 requests for a single download and may not be ideal for mobile browsers due to the need to open a new tab for downloading. It also appears somewhat hacky, at least in my opinion. The API must ensure that URLs are valid for a limited time and/or cannot be used consecutively.

Any Suggestions?

If anyone has suggestions for a clean, modern, state-of-the-art, and efficient way to handle such a typical scenario, I would appreciate your insights.

How do major companies like Google Drive, Dropbox, and Amazon address this issue?

Personally, I lean towards letting the browser handle the file download instead of client-side blob downloads. Is there a way to automatically include bearer tokens as default request headers in the browser when a client clicks on a link (href'ed)?

Why is it challenging for a modern angular-rich client to delegate a secure binary download to the browser effortlessly?

Answer №1

Regrettably, I am not familiar with any solutions to resolve the issue you are facing with FileSaver.js and StreamSaver.js.

However, I encountered a similar problem in the past, which aligns with your concerns about using an "unprotected endpoint."

In such cases, my approach would be to generate a one-time token for the file, which can be included in the URL. While I acknowledge that this may not be the optimal solution, I would appreciate input on what could be considered a "best" practice for this scenario.

Your apprehension about the user experiencing a "flashy" and disruptive behavior is valid. To address this issue, I devised a method involving the injection of a form that triggers the download process.

jQuery('<form action="' + YOUR_URL + '" method="get"></form>')
    .appendTo('body')
    .submit()
    .remove();

By employing this technique, the download operation is seamlessly handled by the browser's standard download dialog, eliminating the undesirable occurrence of a new tab opening and closing abruptly.

Please note:

I have not verified this method for files of your specific size. Nevertheless, it has proven effective for files up to 1GB without any issues. Feel free to give it a try, and hopefully, it will offer a viable solution for your predicament.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

updating firebase data using Angular

Currently, I am attempting to insert a new object into my Firebase database export class AppComponent { courses$: AngularFireList<any[]>; course$;ang author$ constructor(db: AngularFireDatabase) { this.courses$ = db.list('/courses ...

What is the most effective way to use a withLatestFrom within an effect when integrating a selector with props (MemoizedSelectorWithProps) sourced from the action?

I am struggling to utilize a selector with props (of type MemoizedSelectorWithProps) in an effect inside WithLatestFrom. The issue arises because the parameter for the selector (the props) is derived from the action payload, making it difficult for withLat ...

Using p5.js with TypeScript and Webpack is not supported

I'm currently working on a library project that involves utilizing p5.js. Specifications Here is a snippet of my Webpack configuration: const path = require('path'); module.exports = { entry: './start.ts', output: { ...

Tips For Implementing Pagination in Laravel 5.8 with Angular 8

Encountering issues when trying to retrieve the next set of results from the database using Laravel pagination. The results obtained are as follows from the route: api/getMerchants { "merchants": { "current_page": 1, "data": [], // con ...

What is the best way to assign a conditional value to this Angular attribute within my HTML code?

I'm currently developing a web application using Angular and PrimeNG. My question is whether it's possible to conditionally add a PrimeNG component attribute based on the value of a property. In my HTML file, I have the following code: <span [ ...

What is the best way to assign a type based on a variadic type in TypeScript?

TypeScript playground link For my current project, I am designing a custom route handler creator for Express. The goal is to allow passing arbitrary assertions as initial arguments before invoking the route handler callback. Here's an example of how ...

Obtaining the date input value from the ng2-date-picker component in Angular2

I am struggling to extract the value from a date picker input field (ng2-date-picker). Despite attempting various methods to retrieve the value, I have not been successful. For reference, here is the link to the npm package I am utilizing. This represent ...

What is the best way to connect a backend server that is located locally to an Angular frontend?

Currently, my angular app is up and running on an apache server located at http://localhost. However, I also have a backend flask server running on the same machine but on port 5200 (http://localhost:5200). While I can successfully access the backend thro ...

Having trouble uploading big files on your Windows system?

My challenge is to successfully upload a large file using Angular. Specifically, I am attempting to upload a Human Genome tar file, which is a minimum of 2.5gb in size. Strangely, when I try to upload the file from Linux using any browser such as Chrome or ...

Storing Data Efficiently within a Service

I'm completely new to the world of rxjs and asynchronous programming. When a component inquires about data from my service, I want to make sure that I fetch the data from my API only if it's not already available. Here's an example of how I ...

Angular application using ngrx-store-localstorage does not retain data after a page refresh

Looking to incorporate ngrx into my authentication flow with the help of ngrx-store-localstorage for token persistence between browser sessions. After logging in, I can see the token value stored like this: {"token":{"token":"e5cb6515-149c-44df-88d1-4ff1 ...

Tips for Customizing the Width of Your Material UI Alert Bar

At the moment, I have refrained from using any additional styling or .css files on my webpage. The width of the Alert element currently spans across the entire page. Despite my attempts to specify the width in the code snippet below, no noticeable change ...

Angular 5: Issue with Module Resolution: Unable to locate '@angular/forms/src/validators'

Struggling to develop a unique validator using a directive, but encountering the following error: ERROR in ./src/app/CustomValidators/white-space-validator.directive.ts Module not found: Error: Can't resolve '@angular/forms/src/validators' ...

Next.js version 13 will now display the loading.tsx component whenever a setter function for useState() is

I am facing an issue with my client component that has a simple text field which utilizes the useState() hook. Every time I modify the text and call onChange, the loading UI defined in loading.tsx appears before the updated UI. However, this process causes ...

Executing an http.get request in Angular2 without using RxJS

Is there a method to retrieve data in Angular 2 without using Observable and Response dependencies within the service? I believe it's unnecessary for just one straightforward request. ...

Need to monitor a Firebase table for any updates

How can I ensure my Angular 2 app listens to changes in a Firebase table? I am using Angular2, Firebase, and TypeScript, but the listener is not firing when the database table is updated. I want the listener to always trigger whenever there are updates or ...

Exploring the options variables within CLI commander Js action

As a newcomer to developing CLI apps, I've chosen to work with ts-node and commander. However, I'm currently facing a challenge in understanding how to access the options that users pass into my command action. program .version(version) .nam ...

Encountered an issue while resolving dependency tree for angular tslib

When running npm install, I encountered the error shown in this image: https://i.stack.imgur.com/PInQE.png The CLI version is Angular CLI: 9.1.8. Any assistance would be greatly appreciated. Thank you! ...

Error code TS7053 occurs when an element implicitly has an 'any' type because a string expression cannot be used to index an empty object

I have implemented a code snippet that sorts items into groups based on their first character. For example, if the array of item looks like this: {name: 'Foo'} {name: 'Bar'} {name: 'Baz'} The expected result should be: B: ...

Determining the function return type by analyzing an array of functions

If you have a vanilla JavaScript function that accepts an array of callbacks (each returning an object) and combines their outputs, how can TypeScript be used to determine the return type of this function? While ReturnType is typically used for a single ...