繁体   English   中英

从公共 URL 上传到 Amazon S3

[英]Upload to Amazon S3 from public URL

我想使用AWS iOS SDK将图像直接从公共 url 上传到 S3 存储桶。

我的目标是避免下载然后上传图像,这显然会更慢。 我试图天真地将 URL 传递给AWSS3TransferUtility.uploadFile ,如下所示:

import AWSCore
import AWSS3

// ...

AWSS3TransferUtility.register(
    with: AWSServiceManager.default().defaultServiceConfiguration!,
    transferUtilityConfiguration: AWSS3TransferUtilityConfiguration(),
    forKey: "foo"
)

let utility = AWSS3TransferUtility.s3TransferUtility(forKey: "foo")!
let imageURL = URL(string: "https://via.placeholder.com/150/")!

utility
    .uploadFile(
        imageURL,
        bucket: "<bucket name>",
        key: "bar.jpeg",
        contentType: "image/jpg",
        expression: nil,
        completionHandler: nil)
    .continueWith {
        if let error = $0.error {
            print("Error: \(error.localizedDescription)")
        }
        return nil
    }

但它似乎只接受本地文件的 url 并返回错误

操作无法完成。 (com.amazonaws.AWSS3TransferUtilityErrorDomain 错误 4。)

知道这是否可能以及如何实现?

基于@jarmod的想法,我能够使用 Lambda 来做到这一点(此处简化):

const https = require('https');
const AWS = require('aws-sdk');

const s3 = new AWS.S3();

function loadImage(url) {
  return new Promise((resolve, reject) => {
    https.get(url, (resp) => {
      if(resp.statusCode > 200) {
          reject('The image could not be loaded (HTTP ' + resp.statusCode + ')');
      }
      
      resp.setEncoding('binary');
      let chunks = [];

      resp.on('data', (chunk) => {
        chunks.push(Buffer.from(chunk, 'binary'));
      });
      resp.on('end', () => {
        let binary = Buffer.concat(chunks);
        resolve(binary);
      });
      
    }).on("error", (err) => {
      console.log("Error: " + err.message);
      reject(err);
    });
  });
}


exports.handler = async (event, context, callback) => {
  try {
    const url = ...;
    const bucket = ...;
    const key = ...;

    const buffer = await loadImage(url);

    const destparams = {
        Bucket: bucket,
        Key: key,
        Body: buffer,
        ContentType: "image"
    };
    await s3.putObject(destparams).promise();
    
    return "OK";
  } catch(error) {
    return error;
  }
};

使用AWSLambda调用 Lambda 非常简单:

let lambda = AWSLambdaInvocationRequest()!
lambda.functionName = // Lambda name
lambda.invocationType = .requestResponse
let parameters: [String: Any] = [:] // Parameters to pass to the lambda
let payload = try! JSONSerialization.data(withJSONObject: parameters, options: []) 
lambda.payload = payload

AWSLambda.default().invoke(lambda) { response, error in
    //...
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM