Flutter :: Amazon S3图像上传 [英] Flutter :: Amazon S3 Image Upload
问题描述
https://pub.dartlang.org/packages/flutter_amazon_s3
我尝试将使用该库的映像突然上传到Amazon S3,但无法使用任何解决方案?
I try to upload Image using this lib in flutter to Amazon S3 but not working any solution?
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);
但是没有任何日志返回,甚至没有任何错误.
but nothing return in log, even no any error.
推荐答案
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 ,仅当您在应用程序外部使用图片时,这才是问题.
With this code you can send the image, but unfortunately I can't change the file's metadata when making the request, making it binary/octet-stream instead of image/jpeg, this is only a problem if you use the image outside the application.
在此实施方式中,我使用了 Dio 和Amazon Cognito Identity Dart软件包,您可以使用 Amazon Cognito Identity Dart 或 Amazon Cognito Identity Dart 2 ,由于存储库仍处于活动状态,我建议使用第二种方法.
In this implementation I used the Dio and Amazon Cognito Identity Dart packages, you can use either Amazon Cognito Identity Dart or Amazon Cognito Identity Dart 2, I recommend the second option, as the repository is still active.
更新,固定的二进制/八进制流问题
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}" }
]
}
''';
}
}
这篇关于Flutter :: Amazon S3图像上传的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!