2014-03-05 6 views
17

Ich schreibe eine Anwendung, die Bilder von einer URL herunterlädt und sie dann mithilfe der aws-sdk in einen S3-Bucket hochlädt.Laden Sie die Datei von der URL herunter und laden Sie sie ohne Speichern auf AWS S3 hoch - node.js

Ich habe gerade Bilder heruntergeladen und auf diese Weise gespeichert.

request.head(url, function(err, res, body){ 

    request(url).pipe(fs.createWriteStream(image_path)); 

}); 

Und dann die Bilder auf AWS S3 hochladen wie diese

fs.readFile(image_path, function(err, data){ 
    s3.client.putObject({ 
     Bucket: 'myBucket', 
     Key: image_path, 
     Body: data 
     ACL:'public-read' 
    }, function(err, resp) { 
     if(err){ 
      console.log("error in s3 put object cb"); 
     } else { 
      console.log(resp); 
      console.log("successfully added image to s3"); 
     } 
    }); 
}); 

Aber ich möchte das Teil überspringen, wo ich das Bild auf der Festplatte speichern. Gibt es eine Möglichkeit die pipe Antwort von request(url) auf eine Variable zu übertragen und diese dann hochzuladen?

Antwort

16

Hier einige Javascript, dass dies gut funktioniert:

var options = { 
     uri: uri, 
     encoding: null 
    }; 
    request(options, function(error, response, body) { 
     if (error || response.statusCode !== 200) { 
      console.log("failed to get image"); 
      console.log(error); 
     } else { 
      s3.putObject({ 
       Body: body, 
       Key: path, 
       Bucket: 'bucket_name' 
      }, function(error, data) { 
       if (error) { 
        console.log("error downloading image to s3"); 
       } else { 
        console.log("success uploading to s3"); 
       } 
      }); 
     } 
    }); 
+6

Wie geschrieben, der Code den gesamten Körper lädt in Speicher sofort (als String in die Variable "body"). Das bedeutet, dass dies nicht direkt von der Anforderung an S3 erfolgt. OTOH, Anforderung wird ein Pufferobjekt für "body" erstellen, wenn "encoding" null ist; siehe https://github.com/request/request#requestoptions-callback. Ich schlug eine Änderung dieser Antwort vor, um 'encoding: 'binary' in' encoding: null' zu ändern und' body = new Buffer (body, 'binary') 'zu eliminieren. Das würde die Notwendigkeit beseitigen, den gesamten "Körper" im Speicher zu speichern, und ich denke, das stimmt mit der ursprünglichen Frage und Antwort überein. Aber Bewertungen wollten einen Kommentar ... –

+1

Ich versuchte Ihren Ansatz, sowohl mit impliziten und expliziten Codierung, finde ich, dass meine hochgeladenen PNG-Dateien aus irgendeinem Grund beschädigt sind, kann nicht herausfinden, warum. Versuchen, dieses Bild zu kopieren https://openclipart.org/image/250px/svg_to_png/264091/MirrorCarp.png und das ist, was ich in meinem Eimer bekomme http://images.quickhunts.com/clipart/23234234234.png –

+0

@ Ilanlewin Es funktioniert definitiv mit 'png' Bildern, aber stellen Sie sicher, dass Sie' fs.readFile' korrekt implementieren. Es könnte sich geändert haben, seit ich diese Antwort geschrieben habe, müssen Sie vielleicht genauer mit der Codierung sein. Versuchen Sie auch einige 'jpg's oder andere generische Bilder. – Loourr

0

Das ist, was ich tat und funktioniert gut:

const request = require('request-promise') 
 
const AWS = require('aws-sdk') 
 
const s3 = new AWS.S3() 
 

 
const options = { 
 
    uri: uri, 
 
    encoding: null 
 
}; 
 

 
async load() { 
 

 
    const body = await request(options) 
 
    
 
    const uploadResult = await s3.upload({ 
 
    Bucket: 'bucket_name', 
 
    Key : path, 
 
    Body : body, 
 
    }).promise() 
 
    
 
}