【问题标题】:Is there a way to upload to S3 from a url using node.js?有没有办法使用 node.js 从 url 上传到 S3?
【发布时间】:2013-05-24 02:06:42
【问题描述】:

我找到了这个问题,但它似乎没有回答我的问题,因为我认为它仍在谈论本地文件。

我想获取 imgur.com 链接并使用节点将其上传到 S3。 knox 能做到这一点还是我需要使用其他东西?

不知道从哪里开始。

【问题讨论】:

  • 许多答案表明“接受”的答案可能不是正确的,这可能需要更新和支持其他相关答案。当然,没有义务这样做。

标签: node.js amazon-s3 upload knox-amazon-s3-client


【解决方案1】:

我用的不是knox,而是官方的AWS SDK for JavaScript in Node.js。我向带有{encoding: null} 的URL 发出请求,以检索缓冲区中的数据,这些数据可以直接传递给s3.putObject()Body 参数。下面是使用aws-sdkrequest 将远程图像放入存储桶的示例。

var AWS = require('aws-sdk');
var request = require('request');

AWS.config.loadFromPath('./config.json');
var s3 = new AWS.S3();

function put_from_url(url, bucket, key, callback) {
    request({
        url: url,
        encoding: null
    }, function(err, res, body) {
        if (err)
            return callback(err, res);

        s3.putObject({
            Bucket: bucket,
            Key: key,
            ContentType: res.headers['content-type'],
            ContentLength: res.headers['content-length'],
            Body: body // buffer
        }, callback);
    })
}

put_from_url('http://a0.awsstatic.com/main/images/logos/aws_logo.png', 'your_bucket', 'media/aws_logo.png', function(err, res) {
    if (err)
        throw err;

    console.log('Uploaded data successfully!');
});

【讨论】:

  • 我采用的方法完全相同。我的图像文件在 S3 上损坏了 :(
  • +1 为例。我的方法也与此类似,但我遇到了损坏的上传问题。不过,这段代码似乎对我有用。
  • 如果你使用 axios - 设置 header responseType: 'stream'
  • 这对我有用。为了避免损坏的图像问题,我必须确保在请求选项中设置了 encoding: null
  • @Alexander,您的评论对我帮助很大!谢谢!
【解决方案2】:

对于那些正在寻找doesn't involves callbacks 的解决方案并且更喜欢promises 的人,这里是基于@micmia 代码的替代方案:

var AWS = require('aws-sdk'),
request = require('request');


const bucketName='yourBucketName';
const bucketOptions = {...Your options};
var s3 = new AWS.S3(options);

function UploadFromUrlToS3(url,destPath){
    return new Promise((resolve,reject)=> {            
        request({
            url: url,
            encoding: null
        }, function(err, res, body) {        
            if (err){
                reject(err);
            }
            var objectParams = {
                ContentType: res.headers['content-type'],
                ContentLength: res.headers['content-length'],
                Key: destPath,
                Body: body 
            };
            resolve(s3.putObject(objectParams).promise());
        });
    });
}

UploadFromUrlToS3(
    'http://a0.awsstatic.com/main/images/logos/aws_logo.png',
    'your/s3/path/aws_logo.png' )
    .then(function() {
        console.log('image was saved...');
    }).catch(function(err) {
        console.log('image was not saved!',err);
    });

【讨论】:

    【解决方案3】:

    在@Yuri 的帖子的基础上,对于那些想要使用axios 而不是request 和ES6 语法来获得更现代方法的人+ 将所需的Bucket 属性添加到params(它会下载任何文件,不仅是图片):

    const uploadFileToS3 = (url, bucket, key) => {
      return axios.get(url, { responseType: "arraybuffer", responseEncoding: "binary" }).then((response) => {
        const params = {
          ContentType: response.headers["content-type"],
          ContentLength: response.data.length.toString(), // or response.header["content-length"] if available for the type of file downloaded
          Bucket: bucket,
          Body: response.data,
          Key: key,
        };
        return s3.putObject(params).promise();
      });
    }
    
    uploadFileToS3(<your_file_url>, <your_s3_path>, <your_s3_bucket>)
       .then(() => console.log("File saved!"))
       .catch(error) => console.log(error));
    

    【讨论】:

      【解决方案4】:

      与上述答案相同,但使用 fetch:

      async function upload(url: string, key: string, bucket: string) {
        const response = await fetch(url)
        const contentType = response.headers.get("content-type") ?? undefined;
        const contentLength =
          response.headers.get("content-length") != null
            ? Number(response.headers.get("content-length"))
            : undefined;
      
        return s3
          .putObject({
            Bucket: bucket,
            Key: key,
            ContentType: contentType,
            ContentLength: contentLength,
            Body: response.body, // buffer
          })
          .promise();
      }
      

      【讨论】:

        【解决方案5】:

        是的。在 knox README 中有一个这样做的例子

        http.get('http://google.com/doodle.png', function(res){
          var headers = {
              'Content-Length': res.headers['content-length']
            , 'Content-Type': res.headers['content-type']
          };
          client.putStream(res, '/doodle.png', headers, function(err, res){
            // Logic
          });
        });
        

        【讨论】:

        • 没有理由讽刺和粗鲁。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-02-09
        • 2022-01-22
        • 2022-01-07
        • 1970-01-01
        • 1970-01-01
        • 2011-08-13
        • 2018-12-27
        相关资源
        最近更新 更多