2012-08-23 5 views
8

Ich lade eine Datei mit Request hoch.Upload Progress - Request

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

Woher weiß ich, wie viele Daten tatsächlich hochgeladen wurden? Gibt es ein Ereignis, das ich abonnieren kann, oder gibt es eine Eigenschaft von request, die ich abfragen kann?

Wenn keine, was wäre der beste Ansatz zum Hochladen von Daten und wissen, wie viel hochgeladen wurde?

Antwort

6

Ich brauchte einen Griff auf den Upload-Fortschritt für ein weiteres Projekt von mir.

Was ich herausgefunden habe ist, dass Sie die request 's connection._bytesDispatched Eigenschaft abfragen können.

Zum Beispiel:

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

Hinweis: Wenn Sie r kochend wurden, abfragen r.req.connection.socket._bytesDispatched statt.

+0

Sehr schön, danke! – darma

+2

Auf der Suche nach diesem auch. Obwohl es aussieht wie eine interne API (die in zukünftigen 'nodejs' Versionen wahrscheinlich geändert wird), scheint es die einzige Lösung zu sein. –

+2

Das ist schmerzhaft; Ist dies die einzige verfügbare Node.js-Lösung? Im Ernst, warum wurde das Problem des Hochladens von Dateien auf eine HTTP API in Node.js noch nicht gelöst ?! – Sukima

-1

Jemand hat ein schönes Modul erstellt, das im Produktionstack für transloadit läuft (so ist es zuverlässig und gut gepflegt). Sie können es hier finden:

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

-Code sollte wie folgt aussehen:

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

Sie dann Status an einen Client mit Socket.io

Interessante Hinweis drücken könnte: Das war eines der Probleme das führte zur Erstellung des Knotens. In this video Ryan spricht darüber, wie Knoten gestartet wurde, um die beste Möglichkeit zu finden, einen Benutzer in Echtzeit über den Status des Datei-Uploads über das Web zu informieren ... trotzdem schweife ich ab, aber das Video ist eine Uhr wert, wenn Sie interessiert sind in Nodes Geschichte

+1

Nun, das ist für * Empfangen * einer Datei.Ich sende * eine Datei für den Knoten an einen anderen Server. –

+4

Habe gerade 4 Stunden damit verbracht, Google zu suchen. Ist es nur ich, oder gibt es nur wie * five * Menschen auf der Welt, die Dateien ** vom ** Knoten an eine HTTP API senden? Fühlt sich wie der Konsens ist, dass Node.js nur gut für Server-Code und nutzlos für alles andere ist. Seufzer. – Sukima

+0

Es ist nicht nur du .. Ich google stundenlang und habe immer noch keine vernünftige Antwort gefunden .. hast du etwas gefunden? – Besat

-1

Versuchen Sie diesen Ansatz:

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

Ich verbrachte ein paar Stunden alles gültig in request und node Quellen zu finden, und fand schließlich einen anderen Ansatz, der mir mehr richtig anfühlt.

Wir können auf drain Veranstaltung verlassen und bytesWritten Eigenschaft:

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

Alternativ, wenn Sie Fortschritt der Datei Bytes zu handhaben müssen, ist es einfacher, Strom zu verwenden data Ereignis:

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-Puffergröße ist 65536 Bytes und Lese/Drain-Verfahren läuft iterativ.

Das scheint für mich mit node v4.5.0 und request v2.74.0 ziemlich gut zu funktionieren.

+1

Die Abflussmethode hat für mich funktioniert. Allerdings musste ich die Datei pipen und nicht einfach über den body-Parameter übergeben. Wenn ich es über den body-Parameter übergeben würde, würde es mehrere Male leerlaufen, würde es jedoch in schneller Folge tun und nicht, wenn der Server die Daten tatsächlich empfangen hat. Es scheint, dass die Weitergabe über den Körper zu einer Pufferung führt, die nicht die richtige Erfahrung liefert. Prost. – 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); 
}