Flutter 上傳圖片到阿里雲OSS

使用者8454164365033發表於2021-03-31

前言:阿里雲目前沒有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';
複製程式碼

相關文章