Preface
When downloading files with HTTP, you only need to set the relevant response header on the server and use binary to transmit file data, and the client (browser) will receive file data based on the response header. In Node.js, after setting the response header, read the file stream, and then transfer the stream to the response object Response using the “.pipe()” method, you can implement a simple file download server.
1. File download introduction
HTTP implements state interaction based on request header and response header. After obtaining the correct response status of the server, the client will first parse the response header and receive and display data (response body) based on the response header. For file download, the implementation process is as follows:
1. The client initiates a file resource request
2. The server looks for the corresponding file and sets response headers such as " Content-Type " and " Content-Disposition " to represent the "MIME" type and file description of the file respectively.
3. The client parses and receives file data based on the response header returned by the server.
Response header that needs to be set
When setting up file download response headers, in addition to the commonly used HTTP response headers, it is more important to set the following two response headers:
Content-Type: application/octet-streamContent-Disposition: attachment; filename=MyFileName.ext
In the above settings, " Content-Type: application/octet-stream " tells the browser that this is a binary file, and " Content-Disposition " tells the browser that this is an attachment that needs to be downloaded and tells the browser the default file name. If the " Content-Disposition " response header is not added, the browser may download or display the file content, and the processing of different browsers varies.
2. Node.js file download server implementation
Next, we implement a simple file download server based on the Express framework, which mainly includes two functions: browsing server files and downloading files .
2.1 Adding a route
After creating the Express application, add the following two routes:
router.get('/files', function(req, res, next) { // Show server file}); router.get('/file/:fileName', function(req, res, next) { // Implement file download});The two routes added above are used to: display server files and implement file downloads .
2.2 Display server files
To realize the display of server files, you must read the file directory through the " fs " module and perform file/directory checks , etc. You also need to use the " path " module to process the file path. First, these two modules are introduced:
const fs = require('fs');const path = require('path');The implementation code for displaying the server file is as follows:
router.get('/files', function(req, res, next) { // Show server file// File directory var filePath = path.join(__dirname, './'); fs.readdir(filePath, function(err, results){ if(err) throw err; if(results.length>0) { var files = []; results.forEach(function(file){ if(fs.statSync(path.join(filePath, file)).isFile()){ files.push(file); } }) res.render('files', {files:files}); } else { res.end('There is no file in the current directory'); } } });}); In the above code, after reading the directory, the list of downloadable files is displayed through the view file " files.ejs ". The code is as follows:
<!DOCTYPE html><html> <head> <title>Download file selection</title> </head> <body> <h1>Please select the download file: </h1> <% if(files.length>0) {%> <ul> <% files.forEach(function(file){ %> <li> <a href="/file/<%- file %>" target="_blank"><%- file %></a> </li> <%})%> </ul> <%} else {%> <p>No downloadable files...</p> <%}%> </body></html>2.3 Implement file download
When downloading a file, you can first read the file into a " Buffer ", and then send the file data through the " res.send()” or " res.end()” methods, or you can send the file data based on the stream (" Stream "). When using " Stream " to implement file download, you can use the " fs.createReadStream()” method to create a readable stream, and the response object Response is a writable stream. In this way, you only need to transfer the file stream to the Response response stream through the ”.pipe()” method.
The file download implementation code is as follows:
router.get('/file/:fileName', function(req, res, next) { // Implement file download var fileName = req.params.fileName; var filePath = path.join(__dirname, fileName); var stats = fs.statSync(filePath); if(stats.isFile()){ res.set({ 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename='+fileName, 'Content-Length': stats.size }); fs.createReadStream(filePath).pipe(res); } else { res.end(404); }});Summarize
The above is all the content of using Node.js to achieve HTTP file downloads. I hope it will be helpful to everyone to learn Node.js.