Get download progress in Node.js with request

前端 未结 6 2214
清酒与你
清酒与你 2020-12-02 15:27

I\'m creating an updater that downloads application files using the Node module request. How can I use chunk.length to estimate the remaining file

相关标签:
6条回答
  • 2020-12-02 16:19

    In case someone wants to know the progress without the use of other library but only request, then you can use the following method :

    function downloadFile(file_url , targetPath){
        // Save variable to know progress
        var received_bytes = 0;
        var total_bytes = 0;
    
        var req = request({
            method: 'GET',
            uri: file_url
        });
    
        var out = fs.createWriteStream(targetPath);
        req.pipe(out);
    
        req.on('response', function ( data ) {
            // Change the total bytes value to get progress later.
            total_bytes = parseInt(data.headers['content-length' ]);
        });
    
        req.on('data', function(chunk) {
            // Update the received bytes
            received_bytes += chunk.length;
    
            showProgress(received_bytes, total_bytes);
        });
    
        req.on('end', function() {
            alert("File succesfully downloaded");
        });
    }
    
    function showProgress(received,total){
        var percentage = (received * 100) / total;
        console.log(percentage + "% | " + received + " bytes out of " + total + " bytes.");
        // 50% | 50000 bytes received out of 100000 bytes.
    }
    
    downloadFile("https://static.pexels.com/photos/36487/above-adventure-aerial-air.jpg","c:/path/to/local-image.jpg");
    

    The received_bytes variable saves the total of every sent chunk length and according to the total_bytes, the progress is retrieven.

    0 讨论(0)
  • 2020-12-02 16:20
    function download(url, callback, encoding){
            var request = http.get(url, function(response) {
                if (encoding){
                    response.setEncoding(encoding);
                }
                var len = parseInt(response.headers['content-length'], 10);
                var body = "";
                var cur = 0;
                var obj = document.getElementById('js-progress');
                var total = len / 1048576; //1048576 - bytes in  1Megabyte
    
                response.on("data", function(chunk) {
                    body += chunk;
                    cur += chunk.length;
                    obj.innerHTML = "Downloading " + (100.0 * cur / len).toFixed(2) + "% " + (cur / 1048576).toFixed(2) + " mb\r" + ".<br/> Total size: " + total.toFixed(2) + " mb";
                });
    
                response.on("end", function() {
                    callback(body);
                    obj.innerHTML = "Downloading complete";
                });
    
                request.on("error", function(e){
                    console.log("Error: " + e.message);
                });
    
            });
        };
    
    0 讨论(0)
  • 2020-12-02 16:21

    This should get you the total you want:

    req.on( 'response', function ( data ) {
        console.log( data.headers[ 'content-length' ] );
    } );
    

    I get a content length of 9404541

    0 讨论(0)
  • 2020-12-02 16:23

    If you are using "request" module and want to display downloading percentage without using any extra module, you can use the following code:

    function getInstallerFile (installerfileURL) {
    
        // Variable to save downloading progress
        var received_bytes = 0;
        var total_bytes = 0;
    
        var outStream = fs.createWriteStream(INSTALLER_FILE);
    
        request
            .get(installerfileURL)
                .on('error', function(err) {
                    console.log(err);
                })
                .on('response', function(data) {
                    total_bytes = parseInt(data.headers['content-length']);
                })
                .on('data', function(chunk) {
                    received_bytes += chunk.length;
                    showDownloadingProgress(received_bytes, total_bytes);
                })
                .pipe(outStream);
    };
    
    function showDownloadingProgress(received, total) {
        var percentage = ((received * 100) / total).toFixed(2);
        process.stdout.write((platform == 'win32') ? "\033[0G": "\r");
        process.stdout.write(percentage + "% | " + received + " bytes downloaded out of " + total + " bytes.");
    }
    
    0 讨论(0)
  • 2020-12-02 16:28

    I wrote a module that just does what you want: status-bar.

    var bar = statusBar.create ({ total: res.headers["content-length"] })
        .on ("render", function (stats){
          websockets.send (stats);
        })
    
    req.pipe (bar);
    
    0 讨论(0)
  • 2020-12-02 16:30

    Using the cool node-request-progress module, you could do something like this in es2015:

    import { createWriteStream } from 'fs'
    import request from 'request'
    import progress from 'request-progress'
    
    progress(request('http://foo.com/bar.zip'))
     .on('progress', state => {
    
       console.log(state)
    
       /*
       {
           percentage: 0.5,        // Overall percentage (between 0 to 1)
           speed: 554732,          // The download speed in bytes/sec
           size: {
             total: 90044871,      // The total payload size in bytes
             transferred: 27610959 // The transferred payload size in bytes
           },
           time: {
             elapsed: 36.235,      // The total elapsed seconds since the start (3 decimals)
             remaining: 81.403     // The remaining seconds to finish (3 decimals)
           }
       }
       */
    
      })
      .on('error', err => console.log(err))
      .on('end', () => {})
      .pipe(createWriteStream('bar.zip'))
    
    0 讨论(0)
提交回复
热议问题