Flutter 上传图片到阿里云OSS

3,261 阅读2分钟

前言:阿里云目前没有Flutter或者dart官方SDK可集成。这里根据阿里云OSS的文档和参考Java的表单上传的示例来写一个Flutter 上传图片到阿里云OSS的方法。

这里使用的是阿里云OSS PostObject(表单上传) 的方式将图片上传到服务器

http库使用的是dio

dio 表单上传示例

var formData = FormData.fromMap({
  'name': 'wendux',
  'age': 25,
  'file': await MultipartFile.fromFile('./text.txt', filename: 'upload.txt'),
});
var response = await dio.post('/info', data: formData);

准备PostObject(表单上传) 需要的参数

///阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录RAM控制台创建RAM账号。
const String OSSAccessKeyId = '<yourAccessKeyId>';
///用于来生成Signature的
const String accessKeySecret = '<yourAccessKeySecret>';

const String policy = "{\"expiration\": \"2120-01-01T12:00:00.000Z\",\"conditions\": [[\"content-length-range\", 0, 104857600]]}";

关于policy 在阿里云文档上有描述 附录:Post Policy

下面就剩下参数 Signature了,关于如何得到Signature 可以参考 Dart 使用HMAC-SHA1 base64 加密方法

具体上传图片的代码:

  ///这里yourBucketName替换成你们的BucketName
  ///oss-cn-hangzhou: Endpoint以杭州为例,其它Region请按实际情况填写
  final String url = 'https://yourBucketName.oss-cn-hangzhou.aliyuncs.com';

  ///上传图片到阿里云OSS
  Future uploadImage(File imgFile) async{
    ///将Policy进行Base64编码
    String encodePolicy = base64Encode(utf8.encode(policy));
    /// 生成签名
    String signature = getSignature(encodePolicy);
    /// 用 package:path/path.dart 库获取图片名称
    String fileName = basename(imgFile.path);
    /// 让阿里云创建一个flutter的文件夹
    fileName = 'flutter/$fileName';
    var formData = FormData.fromMap({
      'key': fileName,
      'success_action_status':200,///如果该域的值设置为200或者204,OSS返回一个空文档和相应的状态码。
      'OSSAccessKeyId': OSSAccessKeyId,
      'policy': encodePolicy,
      'Signature':signature,
      'Content-Type':'image/jpeg',
      'file': await MultipartFile.fromFile(imgFile.path),
    });
    ///通过FormData上传文件
    var response = await dio.post(url, data: formData,onSendProgress: (int sent,int total){
      print('$sent $total');///打印 上传数据的进度
    });
    print(response.headers);
    print("${response.statusCode} ${response.statusMessage}");
    if(response.statusCode == 200){///图片上传成功
      ///上传图片成功后,该图片的url
      String imageServerPath = '$url/$fileName';
    }
  }

生成signature的方法:

///获取阿里云oss的加密参数Signature
  String getSignature(String encodePolicy){
    var key = utf8.encode(accessKeySecret);
    var bytes = utf8.encode(encodePolicy);

    var hmacSha1 = new Hmac(sha1, key);
    Digest sha1Result = hmacSha1.convert(bytes);
    print("sha1Result:$sha1Result");

    String signature = base64Encode(sha1Result.bytes);
    print("signature:$signature");
    return signature;
  }

最后使用到的dart库和第三方库:

///dio是一个强大的Dart Http请求库
import 'package:dio/dio.dart';
///这里用来进行Base64编码,UTF-8编码的
import 'dart:convert';
///这里用来获取文件file的文件名称的
import 'package:path/path.dart';
///HMAC-SHA1加密用的(这个是第三方库需要依赖)
import 'package:crypto/crypto.dart';