How to download multiple files using ExpressJS one API call - node.js

I'm quite new to expressjs and I'm developing a web application which acts as an API application. There is a react frontend application also. When a button is clicked in the client app it will send an API call to the backend app and will download a file. That scenario is working fine.with the following code.
const file = `${__dirname}/upload-folder/dramaticpenguin.MOV`;
res.download(file); // Set disposition and send it.
});
But now I have a requirement to download multiple files from a button click. How can I do that .
Can someone help me here.

An HTTP response can only have one file. Really, "downloading a file" in HTTP means serving a response with a Content-Disposition: attachment header, to hint to the client that this response should be saved to the filesystem instead of rendered in the browser.
To download multiple files, you want the client code to initiate multiple HTTP requests (probably to different URLs), and the server can respond to each request with a different file. Note that many browsers will refuse to download multiple files in response to a single user action (for fear of flooding the user with unwanted files) or will at least prompt for confirmation before doing so.
If you cannot change your client-side code to make multiple requests, you will need to package your files inside a single file archive.

Related

Recommended practices when developing full-stack applications based on Node.js and AWS

I've been working on the front-end so far, now I'm going to create my first full-stack application. I want to use node.js, express and AWS for this.
At the design stage, I already encountered a few problems. Therefore, I have a few questions and I am asking you for help:
Can I send a message (simple JSON or database value) from the server to all clients who have already opened my home page in a simple and cheap way?
I'm not talking about logged in users, but all who downloaded the main page (GET, '/')?
Using the admin panel ('www.xxxxxxxxx/admin'), I want to send a message to the server once a day. Then I want to change the HTML to display this message. I was thinking to use EJS for this and download this message from the database.
Can I make it better? If someone visits my home page (GET, '/'), EJS will download the message from the database each time! Even though its value is the same for 24 hours. Can I get the value once and then use it until the value is changed? How to store the message? As a JSON on the server? Or maybe in the .env file?
If the user refreshes the page, do I have to pay for calling all AWS functions to build the page each time? Even if nothing has changed in the files?
How to check if the page has new content and then send it to the user, instead of sending the unchanged page files: .html, .js, .css, etc.?
Can I send the user only the changed, dynamically created html file, and not send again unchanged .js and .css files?
Does every user who opens the home page (GET, '/') create a new connection to the server using WebSocket / socket.io?
I will try to answer some of your questions:
Can I send a message (simple JSON or database value) from the server to all clients who have already opened my home page in a simple
and cheap way? I'm not talking about logged in users, but all who
downloaded the main page (GET, '/')?
I guess you mean sending push notifications from the server to the user. This can be done with different services depending on what are you trying to build.
If you are planning to use GraphQL, you already have GraphQL subscriptions out of the box. If you are using AWS, go for Appsync, which is the AWS service for GraphQL.
If you are using REST and a WebApp (not a mobile app), go for AWS IoT using lambdas. Here is a good resource using Serverless Framework (API Gateway + lambdas + IoT) for unauthenticated users: https://www.serverless.com/blog/serverless-notifications-on-aws
If you are planning to use notifications on a mobile app, you can go for SNS, the "de facto" service for push notifications in AWS world.
Using the admin panel ('www.xxxxxxxxx/admin'), I want to send a message to the server once a day. Then I want to change the HTML to display this message. I was thinking to use EJS for this and download this message from the database. Can I make it better? If someone visits my home page (GET, '/'), EJS will download the message from the database each time! Even though its value is the same for 24 hours. Can I get the value once and then use it until the value is changed? How to store the message? As a JSON on the server? Or maybe in the .env file?
Yes, this is the way it's expected to work. The HTML is changed dynamically using frontend code in Javascript; which makes calls (using axios for example) to the backend every time you get into, i.e. "/" path. You can store this data in frontend variables, or even use state management in the frontend using REDUX, VUEX, etc. Remember the frontend code will always run in the browser of your users, not on your servers!
If the user refreshes the page, do I have to pay for calling all AWS functions to build the page each time? Even if nothing has changed in the files?
What you can do is store all your HTML, CSS, Javascript in an S3 bucket and serve from there (this is super cheap, even free till a certain limit). If you want to use Server Side Rendering (SSR), then yes, you'll need to serve your users every time they make a GET request for example. If you use lambda, the first million request per month are free. If you have an EC2 instance to serve your content, then a t2.micro is also free. If you need more than that, you'll need to pay.
How to check if the page has new content and then send it to the user, instead of sending the unchanged page files: .html, .js, .css, etc.?
I think you need to understand how JS (or frameworks like React, Vue or Angular) do this. Basically you download the js code on the client, and the js makes all the functionality to update backend and frontend accordingly. In order to connect frontend with backend, use Axios for example.
Can I send the user only the changed, dynamically created html file, and not send again unchanged .js and .css files?
See answer above. Use frameworks like React or Vue, will help you a lot.
Does every user who opens the home page (GET, '/') create a new connection to the server using WebSocket / socket.io?
Depends on what you code. But by default what happens is the user will make a new GET request everytime he accesses your domain, and that's it. (It's not establishing any connection if you don't tell the code to do so).
Hope this helps!! Happy coding!

Sending client file download link

I have a nodejs backend and I want to send a file download link to the client such that, the file is directly accessible by the client. The file types are JPEG and PNG. Currently, I am serving these files as data-uri but, due to a change in requirements, I must send a download link in response to the file request and, client can download the file later using that link.
Now the current workflow exposes a path /getAvatar. This path should send a response back to the client with the file link. The file, is stored in /assets/avatars relative to the server root. I know I can express.static middleware to send back static resources. However, the methods I have seen so far, res.send() and res.download() both tries to send the file as attachment rather a link that can be used later to download.
Basically, the behavior is like a regular file sharing site where, once a file is clicked, a link to it is generated which, is used for downloading the file. How can I do this?

How to use azure logic app action to download files in browser

I originally created a logic app that would, given a JSON payload, run a stored procedure, transform the results into a CSV table and then email the CSV to a specified email account. Unfortunately requirements changed slightly and instead of emailing the csv they want it to download directly in the browser.
I am unable to get the HTTP response action to tell the browser to download the file using the Content-Disposition header. It looks like this is pulled out of the request by design. Is anyone aware of another action (perhaps a function?) that could be used in place of the HTTP response to get a web browser to download the file rather than returning it as text in the response body?
It does indeed seem to be the case that the Response action doesn't support the Content-Disposition header for some reason. Probably the easiest workround is to proxy the request through a simple HTTP-triggered Azure Function with CORS enabled (or an API on your server) that just fetches the file from the Logic App and then returns it with the Content-Disposition header attached.
NB. Don't rely on <a download="filename"> - most browsers that support the download attribute only respect it for same-origin requests.

Is my picture of a website correct?

I tried analyzing what in essence is a website . I thought of deconstructing or reverse engineering a website . The following are the sequence of events, I speculate or theorize the following sequence of events to be taking place during interaction with a website .
1.Every website is basically a set of computer programs,which get executed when the system where they are stored are contacted .
2.Depending on the processing of the type of request sent by the sender , some xml files , files containing the code to be executed,in response to different events and some script purported for dynamic alteration of the xml files are sent. Out of these xml files .
Out of these xml files , one contains the information about the initial appearance of the page and the furnishing of different controls or event generators on the screen .
4.So when some activity is done in the locality of one event generator , like a mouse click , an event is generated .
The code snippet to respond to the event is executed . If the code contains contacting the server and sending some request then the server is again pinged .
When the server is pinged again , depending on the request sent it again executes some code and in response transfers some more code files ,xml files and scripts to dynamically change the appearance of the page .
Is my understanding about the flow of a website correct ?
A web server is basically just a program sitting on a computer that listens on some TCP port (usually 80 for HTTP, 443 for HTTPS).
Clients (such as browsers) can connect and send a request (in HTTP format) to the server.
The server then sends an HTTP response back.
That's it. That's the basic flow: Connect, request, response.
The response contains a "type" field that tells the client what to do with the data. E.g. it could send an image (which is usually displayed on screen), an audio file (which is played), or a "normal" web page in HTML format.
HTML contains structured information about page content and layout, and may contain references to other resources such as images, style sheets, and scripts. A browser automatically fetches these resources (another HTTP request/response) and processes them.
Scripts can be used to customize the behavior on the client side. These are typically written in JavaScript and make use of an API exposed by the browser for interacting with the current page. They can e.g. register "click" handlers to define what happens when the user clicks on some page element.
XML may or may not be used internally by the web server. It doesn't really matter as far as clients are concerned.
If you want to learn more about this, I suggest researching HTTP, HTML, CSS, and JavaScript. MDN has some good articles, for example.

send a file FROM node js

I've read a million different pages on how to send a file to node js from some client, but that is NOT what I'm looking for. I'd like to send a file from out client side code to a 3rd party storage system, but they don't account for the options preflight method and there is nothing I can do about that, nor can I use a different 3rd party service.
So what I'd like to do is send a file from the client, to our node js backend service, and then from the service, send the file to the 3rd party. I understand and have done many times, http request from node but I'm always sending an object of some sort. The difference here is that the object I want to send is a file.
Question: How do I get a file object together and then send that through an HTTPS PUT?
PS: I'm also running just plain vanilla node js.

Resources