我正在编写一个应用程序,该应用程序从 url 下载图像,然后使用 aws-sdk 将其上传到 S3 存储桶。
以前我只是下载图像并像这样将它们保存到磁盘。
request.head(url, function(err, res, body){
request(url).pipe(fs.createWriteStream(image_path));
});
然后像这样将图像上传到 AWS S3
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");
}
});
});
但是我想跳过将图像保存到磁盘的部分。有没有办法pipe
request(url)
的响应到变量,然后上传?
这里有一些JavaScript可以很好地做到这一点:
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");
}
});
}
});
这就是我所做的并且效果很好:
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()
}
这样的事情呢:
const stream = require('stream');
const request = require('request');
const s3 = new AWS.S3()
const pass = new stream.PassThrough();
request(url).pipe(pass);
s3.upload({
Bucket: 'bucket_name',
Key: path,
Body: pass,
});
import axios from "axios";
import aws from 'aws-sdk'
import crypto from 'crypto'
const s3 = new aws.S3();
export const urlToS3 = async ({ url, bucket = "rememoio-users", key = Date.now() + crypto.randomBytes(8).toString('hex') + ".png" }) => {
try {
const { data } = await axios.get(url, { responseType: "stream" });
const upload = await s3.upload({
Bucket: bucket,
ACL: 'public-read',
Key: key,
Body: data,
}).promise();
return upload.Location;
} catch (error) {
console.error(error);
throw new Error;
}
};
你可以像这样用Axios实现。有关详细信息,请参阅此内容。
const axios = require("axios");
const AWS = require("aws-sdk");
const { PassThrough } = require("stream");
const s3 = new AWS.S3({
accessKeyId: "accessKeyId",
secretAccessKey: "accessKey",
region: "region",
});
const bucket = "BucketName";
const key = "key";
const uploadToS3 = async (bucket, key) => {
try {
const stream = await axios.get(url, { responseType: "stream" });
const passThrough = new PassThrough();
const response = s3.upload({ Bucket: bucket, Key: key, Body: passThrough });
stream.data.pipe(passThrough);
return response.then((data) => data.Location).catch((e) => console.error(e));
} catch (error) {
console.error(error);
}
};
uploadToS3(bucket, key);
使用 fetch:
//fetch image from url
const imageResp = await fetch(
'<image url>'
)
// transform to arrayBuffer
const imageBinaryBuffer = Buffer.from(await imageResp.arrayBuffer())
//get image type
const imageType = imageName.toLowerCase().includes(".png")
? "image/png"
: "image/jpg";
//get presigned url and data [this can be different on your end]
const presignedResponse = await getPresignedURL(imageBinaryBuffer, imageName, imageType)
const s3Result = presignedResponse.data
// build the formData
let formData = new FormData()
Object.keys(s3Result.fields).forEach(key => {
formData.append(key, s3Result.fields[key]);
});
formData.append("file", imageBinaryBuffer);
const s3resp = await fetch(s3Result.url, {
method: "POST",
body: formData,
});
return s3resp.headers.location