【问题标题】:Flutter :: Amazon S3 Image UploadFlutter :: Amazon S3 图像上传
【发布时间】:2019-09-20 22:57:30
【问题描述】:

https://pub.dartlang.org/packages/flutter_amazon_s3

我尝试使用这个库将图像上传到 Amazon S3,但没有解决任何问题?

import 'package:flutter_amazon_s3/flutter_amazon_s3.dart';

String uploadedImageUrl = await FlutterAmazonS3.uploadImage(
      _image.path, BUCKET_NAME, IDENTITY_POOL_ID);

print("_uploadImageToAWS uploadedImageUrl ::" + uploadedImageUrl);

但日志中没有任何返回,甚至没有任何错误。

【问题讨论】:

  • 你能分享一下你写的代码和你遇到的错误吗?这将对每个人都有帮助。
  • @Vishal Dhaduk 你找到上传图片到 s3 了吗?因为我实现了它,但是我在 Unhandled Exception: PlatformException(error, Can't downgrade database from version 6 to 5, null) 下面得到了这个异常,你能帮我解决吗?

标签: image amazon-s3 flutter


【解决方案1】:
class UploadAWS {
  Future<String> uploadImage(File image, String path) async {
    final Dio _client = Dio();
    _client.interceptors.add(LogInterceptor());
    final int length = await image.length();
    final String filename = 'testFile.jpg';
    final String key = path + filename;
    final Policy policy = Policy.fromS3PreSignedPost(
      key,
      AWSBucket,
      15,
      AWSaccessKey,
      length,
      AWSsessionToken,
      region: AWSregion,
    );
    final List<int> signKey =
        SigV4.calculateSigningKey(AWSsecretKey, policy.datetime, AWSregion, AWSservice);
    final String signature = SigV4.calculateSignature(signKey, policy.encode());
    final FormData formData = FormData.fromMap({
      'key': policy.key,
      'acl': 'public-read',
      'X-Amz-Algorithm': 'AWS4-HMAC-SHA256',
      'X-Amz-Credential': policy.credential,
      'X-Amz-Date': policy.datetime,
      'Policy': policy.encode(),
      'X-Amz-Signature': signature,
      'x-amz-security-token': AWSsessionToken,
      'file': await MultipartFile.fromFile(
        image.path,
        filename: filename,
      )
    });
    Response response = await _client.post('https://$AWSBucket.s3.amazonaws.com', data: formData);
    _client.close();
    return response.headers.map['location'].first;
  }
}

class Policy {
  String expiration;
  String region;
  String bucket;
  String key;
  String credential;
  String datetime;
  String sessionToken;
  int maxFileSize;

  Policy(this.key, this.bucket, this.datetime, this.expiration, this.credential,
      this.maxFileSize, this.sessionToken,
      {this.region = AWS_REGION_FTALK});

  factory Policy.fromS3PreSignedPost(
    String key,
    String bucket,
    int expiryMinutes,
    String accessKeyId,
    int maxFileSize,
    String sessionToken, {
    String region,
  }) {
    final datetime = SigV4.generateDatetime();
    final expiration = (DateTime.now())
        .add(Duration(minutes: expiryMinutes))
        .toUtc()
        .toString()
        .split(' ')
        .join('T');
    final cred =
        '$accessKeyId/${SigV4.buildCredentialScope(datetime, region, 's3')}';
    final policy = Policy(
        key, bucket, datetime, expiration, cred, maxFileSize, sessionToken,
        region: region);
    return policy;
  }

  String encode() {
    final bytes = utf8.encode(toString());
    return base64.encode(bytes);
  }

  @override
  String toString() {
    return '''
{ "expiration": "${this.expiration}",
  "conditions": [
    {"bucket": "${this.bucket}"},
    ["starts-with", "\$key", "${this.key}"],
    {"acl": "public-read"},
    ["content-length-range", 1, ${this.maxFileSize}],
    {"x-amz-credential": "${this.credential}"},
    {"x-amz-algorithm": "AWS4-HMAC-SHA256"},
    {"x-amz-date": "${this.datetime}" },
    {"x-amz-security-token": "${this.sessionToken}" }
  ]
}
''';
  }
}

使用此代码您可以发送图像,但不幸的是,在发出请求时我无法更改文件的元数据,使其 binary/octet-stream 而不是 image/jpeg,只有在应用程序之外使用图像时才会出现问题

在此实施中,我使用了 Dio 和 Amazon Cognito Identity Dart 包,您可以使用 Amazon Cognito Identity DartAmazon Cognito Identity Dart 2,我推荐第二个选项,因为存储库仍然处于活动状态。

更新,修复二进制/八位字节流问题

class UploadAWS {
  Future<String> uploadImage(File image, String path) async {
    final Dio _client = Dio();
    _client.interceptors.add(LogInterceptor());
    final int length = await image.length();
    final String filename = 'testFile.jpg';
    final String key = path + filename;
    final Policy policy = Policy.fromS3PreSignedPost(
      key,
      AWSBucket,
      15,
      AWSaccessKey,
      length,
      AWSsessionToken,
      region: AWSregion,
    );
    final List<int> signKey =
        SigV4.calculateSigningKey(AWSsecretKey, policy.datetime, AWSregion, AWSservice);
    final String signature = SigV4.calculateSignature(signKey, policy.encode());
    final FormData formData = FormData.fromMap({
      'key': policy.key,
      'acl': 'public-read',
      'X-Amz-Algorithm': 'AWS4-HMAC-SHA256',
      'X-Amz-Credential': policy.credential,
      'X-Amz-Date': policy.datetime,
      'Policy': policy.encode(),
      'X-Amz-Signature': signature,
      'x-amz-security-token': AWSsessionToken,
      'Content-Type': 'image/jpeg',
      'file': await MultipartFile.fromFile(
        image.path,
        filename: filename,
      )
    });
    Response response = await _client.post('https://$AWSBucket.s3.amazonaws.com', data: formData);
    _client.close();
    return response.headers.map['location'].first;
  }
}

class Policy {
  String expiration;
  String region;
  String bucket;
  String key;
  String credential;
  String datetime;
  String sessionToken;
  int maxFileSize;

  Policy(this.key, this.bucket, this.datetime, this.expiration, this.credential,
      this.maxFileSize, this.sessionToken,
      {this.region = AWS_REGION_FTALK});

  factory Policy.fromS3PreSignedPost(
    String key,
    String bucket,
    int expiryMinutes,
    String accessKeyId,
    int maxFileSize,
    String sessionToken, {
    String region,
  }) {
    final datetime = SigV4.generateDatetime();
    final expiration = (DateTime.now())
        .add(Duration(minutes: expiryMinutes))
        .toUtc()
        .toString()
        .split(' ')
        .join('T');
    final cred =
        '$accessKeyId/${SigV4.buildCredentialScope(datetime, region, 's3')}';
    final policy = Policy(
        key, bucket, datetime, expiration, cred, maxFileSize, sessionToken,
        region: region);
    return policy;
  }

  String encode() {
    final bytes = utf8.encode(toString());
    return base64.encode(bytes);
  }

  @override
  String toString() {
    return '''
{ "expiration": "${this.expiration}",
  "conditions": [
    {"bucket": "${this.bucket}"},
    ["starts-with", "\$key", "${this.key}"],
    ["starts-with", "\$Content-Type", "image/"],
    {"acl": "public-read"},
    ["content-length-range", 1, ${this.maxFileSize}],
    {"x-amz-credential": "${this.credential}"},
    {"x-amz-algorithm": "AWS4-HMAC-SHA256"},
    {"x-amz-date": "${this.datetime}" },
    {"x-amz-security-token": "${this.sessionToken}" }
  ]
}
''';
  }
}

【讨论】:

    【解决方案2】:
    import 'package:flutter_amazon_s3/flutter_amazon_s3.dart';
    Future getImage() async {
    var _image = await ImagePicker.pickImage(source: ImageSource.gallery);
    print('getImage ${image.path}');//print image path
    String uploadedImageUrl = await FlutterAmazonS3.uploadImage(
      _image.path, BUCKET_NAME, IDENTITY_POOL_ID);
    print('uploadedImageUrl ===== $uploadedImageUrl');
    }
    

    我正在使用此代码在 S3 上上传图像,它似乎无法正常工作。我没有上传ImageUrl

    【讨论】:

    • 欢迎来到 Stackoverflow!这不是答案,普里扬卡;这是一条评论。您可能想删除您的答案。此外,您的代码看起来与 Vishal 的代码相似。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-17
    • 2018-01-10
    • 2015-01-05
    • 1970-01-01
    • 2011-11-10
    • 2018-07-16
    • 2011-04-16
    相关资源
    最近更新 更多