Загрузка Прогресс - Запрос

Я загружаю файл, используя Request.

req = request.post url: "http://foo.com", body: fileAsBuffer, (err, res, body) ->
    console.log "Uploaded!"

Как узнать, сколько данных действительно было загружено? Есть ли какое-то событие, на которое я могу подписаться, или есть свойство Request, которое я могу опросить?

Если нет, то какой лучший способ загрузить данные и узнать, сколько было загружено?

Ответ 1

Мне нужен ручка для выполнения загрузки для еще одного моего проекта.

Я узнал, что вы можете опросить свойство request connection._bytesDispatched.

Например:

r = request.post url: "http://foo.com", body: fileAsBuffer
setInterval (-> console.log "Uploaded: #{r.req.connection._bytesDispatched}"), 250

Примечание. Если вы переходите к r, вместо опроса r.req.connection.socket._bytesDispatched.

Ответ 2

Я потратил пару часов, чтобы найти что-нибудь правильное в источниках request и node, и, наконец, нашел другой подход, который кажется мне более правильным.

Мы можем положиться на событие drain и свойство bytesWritten:

request.put({
  url: 'https://example.org/api/upload',
  body: fs.createReadStream(path)
}).on('drain', () => {
  console.log(req.req.connection.bytesWritten);
});

В качестве альтернативы, если вам нужно обработать ход файловых байтов, проще использовать событие потока data:

let size = fs.lstatSync(path).size;
let bytes = 0;

request.put({
  url: 'https://example.org/api/upload',
  body: fs.createReadStream(path).on('data', (chunk) => {
    console.log(bytes += chunk.length, size);
  })
});

Размер потокового буфера составляет 65536 байт, и процедура чтения/утечки выполняется итеративно.

Кажется, это работает довольно хорошо для меня с node v4.5.0 и request v2.74.0.

Ответ 3

var request = require('request');
    var fs = require('fs');  
    let path ="C:/path/to/file";
    var formData = {
        vyapardb: fs.createReadStream(path)
    };

    let size = fs.lstatSync(path).size;

    var headers = {
        'Accept' : 'application/json',
        'Authorization' : 'Bearer '+token,
    };

    var r = request.post({url:'http://35.12.13/file/upload', formData: formData,  headers: headers}, function optionalCallback(err, httpResponse, body) {
        clearInterval(q);

    });
    var q = setInterval(function () {
        var dispatched = r.req.connection._bytesDispatched;
        let percent = dispatched*100/size;
         console.dir("Uploaded: " + percent + "%");

    }, 250);
}

Ответ 4

Я знаю, что это старое, но я только что нашел библиотеку 'progress-stream', которая не была упомянута и делает это очень хорошо. https://www.npmjs.com/package/progress-stream

const streamProg = require('progress-stream');
const fs = require('fs');
const request = require('request');

const myFile = 'path/to/file.txt';
const fileSize = fs.statSync('path/to/file.txt').size;
const readStream = fs.createReadStream(myFile);
const progress = streamProg({time: 1000, length: fileSize})
    .on('progress', state => console.log(state));

readStream.pipe(progress).pipe(request.put({url: 'SOMEURL/file.txt'}));

Точно так же это может быть использовано между загрузкой канала.

Ответ 5

Кто-то создал хороший модуль для выполнения этого, который был запущен в производственном стеке для transloadit (так что он надежный и хорошо поддерживается). Вы можете найти его здесь:

https://github.com/felixge/node-formidable

Код должен выглядеть так:

var formidable = require('formidable'),
    http = require('http'),

    util = require('util');

http.createServer(function(req, res) {
  if (req.url == '/upload' && req.method.toLowerCase() == 'post') {
    // parse a file upload
    var form = new formidable.IncomingForm();
    form.parse(req, function(err, fields, files) {
      res.writeHead(200, {'content-type': 'text/plain'});
      res.write('received upload:\n\n');
      res.end(util.inspect({fields: fields, files: files}));
    });
    return;
  }

  // show a file upload form
  res.writeHead(200, {'content-type': 'text/html'});
  res.end(
    '<form action="/upload" enctype="multipart/form-data" method="post">'+
    '<input type="text" name="title"><br>'+
    '<input type="file" name="upload" multiple="multiple"><br>'+
    '<input type="submit" value="Upload">'+
    '</form>'
  );
}).listen(80);

Затем вы можете нажать статус клиенту, используя Socket.io

Интересное примечание. Это была одна из проблем, которая привела к созданию Node. В это видео Райан рассказывает о начале Node, пытаясь найти лучший способ уведомления пользователя, в реальном времени о статусе файла загрузите через Интернет... в любом случае я отвлекаюсь, но видео стоит посмотреть, если вас интересует история Node

Ответ 6

Попробуйте этот подход:

var file = fs.createWriteStream("largefile.jpg");
var totalbytes = request.headers['content-length'];
var donesofar = 0;

request.pipe(file);
request.on('data', function(chunk){
    donesofar += chunk.length;
    var progress = (donesofar / totalbytes) * 100;
    response.write(parseInt(progress, 10) + "%\n");

});