2012-08-23 16 views
8

Przesyłam plik przy użyciu Request.Postęp przesyłania - żądanie

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

Skąd wiadomo, ile danych zostało przesłanych? Czy jest jakieś wydarzenie, które mogę zasubskrybować, czy też istnieje własność request, którą mogę sondować?

Jeśli nie, to jakie jest najlepsze podejście do przesyłania danych i wiedzieć, ile zostało przesłane?

Odpowiedz

6

Potrzebowałem uchwytu dotyczącego postępu przesyłania dla kolejnego mojego projektu.

Co dowiedziałem się, że można odpytać o właściwość request o wartości request.

Na przykład:

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

Uwaga: Jeśli zostały rurociągów do r, sondowania r.req.connection.socket._bytesDispatched zamiast.

+0

Bardzo ładne, dziękuję! – darma

+2

Szuka tego również. Chociaż wygląda na wewnętrzny API (wydaje się, że będzie to zmiana w przyszłych wersjach 'nodejs'), wydaje się, że jest to jedyne rozwiązanie. –

+2

To jest bolesne; czy to jedyne dostępne rozwiązanie Node.js? Poważnie, dlaczego problem przesyłania plików do interfejsu API HTTP w Node.js nie został rozwiązany ?! – Sukima

-1

Ktoś stworzył ładny moduł do wykonania tego, który działał w stosie produkcyjnym dla transloadit (więc jest niezawodny i dobrze utrzymany). Można go znaleźć tutaj:

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

Kod powinien wyglądać następująco:

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); 

Następnie można wcisnąć status klienta korzystającego Socket.io

Ciekawe Uwaga: To był jeden z problemów które doprowadziły do ​​stworzenia Węzła. W numerze this video Ryan opowiada o tym, jak węzeł został rozpoczęty, próbując znaleźć najlepszy sposób powiadomienia użytkownika, w czasie rzeczywistym, o stanie przesyłania plików przez Internet ... w każdym razie dygresja, ale film wart jest obejrzenia, jeśli jesteś zainteresowany w historii Node

+1

Cóż, za odbieranie * pliku.Wysyłam * plik dla węzła na inny serwer. –

+4

Po prostu spędziłem około 4 godzin na przeszukiwaniu Google. Czy to tylko ja, czy jest tam tylko jak * pięć * osób na świecie, które wysyłają pliki ** z ** węzła do API HTTP? Wygląda na to, że Node.js jest dobre tylko dla kodu serwera i jest bezużyteczne dla czegokolwiek innego. Westchnienie. – Sukima

+0

To nie tylko ty .. Szukam go przez wiele godzin i nadal nie znalazłem żadnej rozsądnej odpowiedzi. Czy znalazłeś coś? – Besat

-1

Spróbuj tego podejścia:

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"); 

}); 
3

spędziłem kilka godzin na znalezienie czegoś ważnego w request i node źródeł, iw końcu znalazłem innego podejścia, które czuje się bardziej poprawne do mnie.

Możemy polegać na drain zdarzenia i bytesWritten nieruchomości:

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

Alternatywnie, jeśli trzeba obsłużyć postęp bajtów plików, łatwiej jest stosować strumienia data zdarzenie:

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); 
    }) 
}); 

Stream rozmiar bufora jest 65536 bajtów, a procedura odczytu/drenowania działa iteracyjnie.

Wydaje się, że działa to całkiem dobrze dla mnie z node v4.5.0 i request v2.74.0.

+1

Metoda drenażu zadziałała dla mnie. Jednak musiałem potokować plik, a nie tylko przekazywać go za pomocą parametru body. Kiedy przekazałem go za pomocą parametru body, drenaż byłby kilkakrotny, ale robiłby to w krótkich odstępach czasu, a nie wtedy, gdy serwer faktycznie otrzymywał dane. Wydaje się, że przekazywanie go przez ciało powoduje, że jest buforowany, co nie daje właściwego doświadczenia. Twoje zdrowie. – McP

0
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); 
} 
Powiązane problemy