一.首先获取文件的本地路径。
二.调后台接口返回oss图片上传需要的参数:accessKeyId, accessKeySecret, bucket, endPoint ,securityToken。
三.对数据进行处理,设置请求的参数
四.获取dio请求返回的路径
使用的依赖:
dio: ^5.0.0
crypto: ^3.0.2 #加密处理
intl: ^0.18.0 #国际化 因为请求参数需要设置日期
oss图片上传dart文件如下所示:
import 'dart:collection';import 'dart:convert';import 'dart:math';import 'dart:typed_data';import 'package:crypto/crypto.dart';import 'package:dio/dio.dart';import 'package:intl/intl.dart';import '../constants/constants.dart';import 'package:intl/date_symbol_data_local.dart';//intl包下的String ossAccessKeyId = '替换成自己的accessKeyId';String ossAccessKeySecret = '替换成自己的accessKeySecret';// oss设置的bucket的名字String bucketName = '替换成自己的bucket';String ossEndPoint = '替换成自己的endPoint';//oss-cn-String ossSecurityToken = '替换成自己的securityToken';String host = "$bucketName.$ossEndPoint";String url = 'https://$host';class OssUtil{OssUtil._internal();factory OssUtil() => _instance;static late final OssUtil _instance = OssUtil._internal();Future<String> ossUploadImage(Uint8List imageData,String pathName,{required String fileType, String? directory = "community"}) async {String date = getGMTDateString();String contentType = 'image/$fileType';//签名相关//请求头SplayTreeMap<String, String> treeMap = SplayTreeMap();treeMap["Content-Type".toLowerCase()] = contentType.trim();treeMap["Content-MD5".toLowerCase()] = "";treeMap["Date".toLowerCase()] = date.trim();treeMap["x-oss-security-token".toLowerCase()] = ossSecurityToken.trim();String headString = "PUT\n";treeMap.forEach((key, value) {if (key.startsWith("x-oss-")) {headString += key;headString += ':';headString += value;} else {headString += value;}headString += '\n';});String contentString = "/$bucketName/$pathName";String contentToSign = headString + contentString;List<int> key = utf8.encode(ossAccessKeySecret);List<int> data = utf8.encode(contentToSign);var signaturePre = Hmac(sha1, key).convert(data).bytes;//最后一步,将上述所得进行base64 编码String signature = base64.encode(signaturePre);String signatureA = "OSS " + ossAccessKeyId + ":" + signature;Dio dio = Dio();dio.options.responseType = ResponseType.plain;dio.interceptors.add(InterceptorsWrapper(onRequest: (options, handler) {options.headers["Authorization"] = signatureA;options.headers["Host"] = host;options.headers["x-oss-security-token"] = ossSecurityToken;options.contentType = contentType;options.headers["date"] = date;//必须要设置日期 不设置日期报错 403handler.next(options);}));try {// 发送请求var resultUrl = url + "/$pathName";//必须转成这个类型才可以Stream<List<int>> stream = Stream.value(imageData);var rep = await dio.put(resultUrl, data: stream);// 成功后返回文件访问路径return UPLOAD_IMAGE_BASE_URL+"$pathName";} catch (e) {return '';}}String getRandom(int num) {String alphabet = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM";String left = "";for (var i = 0; i < num; i++) {left = left + alphabet[Random().nextInt(alphabet.length)];}return left;}//这个时间必须调用初始化,并且的时间要减去8小时,要不然会报错,服务器时间和请求时间相差太大,因为是GMT时间,所以当前时间我们是东八区的时间,所以相差8小时。String getGMTDateString() {initializeDateFormatting();var date = DateTime.now();date = date.subtract(const Duration(hours: 8));//当前时间减去8个小时// date = date.add(const Duration(hours: 8));//当前时间加上8个小时return DateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'", 'en').format(date);}}
此类使用方式:
stsUploadResponse(File file) async{try {if (!LoginPrefs(context).isLogin()) {LoginPrefs(context).logout();Navigator.of(context).pushNamedAndRemoveUntil("login", ModalRoute.withName("login"));return;}StsUploadResponseRequestEntity stsUploadResponseRequestEntity=new StsUploadResponseRequestEntity();stsUploadResponseRequestEntity.fileType=1;stsUploadResponseRequestEntity.fileName=file.path;StsUploadResponseResponseEntity stsUploadResponseResponseEntity =await NetWorkWithToken(context).stsUploadResponse(stsUploadResponseRequestEntity);//调接口获取oss需要的参数if (stsUploadResponseResponseEntity != null) {String accessKeyId=stsUploadResponseResponseEntity.accessKeyId;String accessKeySecret=stsUploadResponseResponseEntity.accessKeySecret;String securityToken=stsUploadResponseResponseEntity.securityToken;String bucket=stsUploadResponseResponseEntity.bucket;String endPoint=stsUploadResponseResponseEntity.endPoint;String ossFileFullName=stsUploadResponseResponseEntity.ossFileFullName;ossAccessKeyId=accessKeyId;ossAccessKeySecret=accessKeySecret;bucketName=bucket;ossEndPoint=endPoint;ossSecurityToken=securityToken;String fileType=ossFileFullName.substring(ossFileFullName.lastIndexOf('.')+1);print(fileType);Uint8List imageData;imageData=await file.readAsBytes();String path=await OssUtil().ossUploadImage(imageData, ossFileFullName,fileType: fileType);print('阿里云返回的路径:'+path);return path;}} on DioError catch (e) {print(e.message!);} finally {}}