This tag can be configured in Node.JS to realize the segmented download of files. This article introduces Node.JS segment point continuation: the implementation method of Nginx configuration file segment download function. Please refer to it for your reference.
Html5 provides a new Range tag to implement the segmented download of files. This tag can be configured in Node.JS to realize the segmented download of files.
Header tag
Request Header: download file content after 3744
range: bytes=3744-
Return Response Header: the total length of the file is 15522643 bytes
accept-ranges': 'bytes' content-range': 'bytes */15522643'
Nginx configuration
First, configure Nginx to support range tag return. Simply add add header accept ranges bytes; this line is enough.
server { listen 80; server_name adksdf.com; location ~ ^/(img/|js/|css/|upload/|font/|fonts/|res/|icon) { add_header Access-Control-Allow-Origin *; add_header Accept-Ranges bytes; root /var/www/...; access_log off; expires max; } ... }
After enabling, if node.js sends the request information with range header, nginx will return the information with range:
This is a complete Response Header. Note that the content length here is not the total length of the file, but the length of the current range.
{ server: 'nginx', date: 'Wed, 24 Jan 2018 02:43:20 GMT', 'content-type': 'application/zip', 'content-length': '12420187', 'last-modified': 'Tue, 16 Jan 2018 12:09:47 GMT', connection: 'close', etag: '"5a5deb8b-ecdb53"', expires: 'Thu, 31 Dec 2037 23:55:55 GMT', 'cache-control': 'max-age=315360000', 'access-control-allow-origin': '*', 'accept-ranges': 'bytes', 'content-range': 'bytes 3102456-15522642/15522643' }
The total size of the file can be obtained according to the content range in the header.
Node.JS implementation
This example first detects the lower half of the local file, then creates a file stream in 'r +' read-write mode, and writes the response stream to the file.
Here you will add support for range to the statement file.
var reqOptions = { url: packageUrl, headers: {} } var filepath = '/path/to/your/part/file' var fileOptions = {} fs.stat(filepath, function(err, states) { if (states) { //Range: bytes=3744- reqOptions.headers['range'] = 'bytes=' + states.size + '-' fileOptions = { start: states.size, flags: 'r+' } } //Create http object method var reqUrl = reqOptions.url var urlObj = url.parse(reqUrl) var options = { hostname : urlObj.hostname , port : urlObj.port , path : urlObj.pathname , headers : reqOptions.headers || {} } var req = http.request(options, function(res) { var receives = [] var err = null var statusCode = res.statusCode var headers = res.headers var ws = fs.createWriteStream(filepath, fileOptions) ws.on('error', function(e) { console.log('ws error', e) }) res.on('data', function(chrunk) { ws.write(chrunk) }) res.on('error', function(err) { ws.end() }) res.on('end', function() { ws.end() }) }) req.on('error', function(e) { cb && cb(e, null, {}) }) req.end() ... })
Return to Header
In the request nginx may return other status code s, such as 206 or 416, meaning as follows:
206 Partial Content
Part of the file content is returned
416 Requested Range Not Satisfiable
Requested range exceeds file size
The above is for you. I hope it will help you in the future.
Related articles:
vue multi entry file building example of vue multi page building
An angular method level cache annotation (decorator)
Solve the problem of not refreshing the page data when the route of vue changes
Encountered in project:
downloadFilePart :function(uri,uridownload,filename,event) { var request = require('request') const SINGLE = 1024 * 1024 * 1024 ; const file =path.join(store.globalData.storePath, filename); var fs = require('fs'); request( { method: 'GET', uri: uri, }, (err, res) => { const size = Number(res.headers['content-length']); let length = 1; if (size>SINGLE) { length = parseInt(size / SINGLE)+1; } var num = 0; for (let i=0; i<length;i++) { let start = i * SINGLE; let end = i == length-1 ? size - 1: (i + 1) * SINGLE - 1; request({ method: 'GET', uri: uridownload, headers: { 'range': `bytes=${start}-${end}` }, }).pipe(fs.createWriteStream(file, {flags:'w',start, end})).on('close', function (a) { num++ console.info('%c Download backup case data-'+start+'-Time:' + new Date().getTime(), "color:red") if (num == length) {//You must accept all requests before sending the download completed return. Otherwise, the zip file data is abnormal. event.sender.send('downloadFile-reply', 'success'); // Asynchronous return request } }); } }) },