flutter直接上传文件到阿里云oss

代码实现

以下是我写的一个上传oss的类,只需要替换ossAccessKeyId, ossAccessKeySecret, bucket, url, expiration这几个参数就可以直接实现上传

import 'dart:convert';
import 'dart:io';
import 'dart:math';
import 'package:crypto/crypto.dart';
import 'package:dio/dio.dart';

class UploadOss {

  static String ossAccessKeyId = 'ossAccessKeyId';

  static String ossAccessKeySecret = 'ossAccessKeySecret';
  // oss设置的bucket的名字
  static String bucket = 'bucketName';
  // 发送请求的url,根据你自己设置的是哪个城市的
  static String url = 'https://$bucket.oss-cn-hangzhou.aliyuncs.com';

  // 过期时间
  static String expiration = '2025-01-01T12:00:00.000Z';

  /**
   * @params file 要上传的文件对象
   * @params rootDir 阿里云oss设置的根目录文件夹名字
   * @param fileType 文件类型例如jpg,mp4等
   * @param callback 回调函数我这里用于传cancelToken,方便后期关闭请求
   * @param onSendProgress 上传的进度事件
   */

  static Future<String> upload({ File file , String rootDir = 'moment', String fileType, Function callback, Function onSendProgress}) async {
    String policyText = '{"expiration": "$expiration","conditions": [{"bucket": "$bucket" },["content-length-range", 0, 1048576000]]}';

    // 获取签名
    String signature = getSignature(policyText);

    BaseOptions options = new BaseOptions();
    options.responseType = ResponseType.plain;

    //创建dio对象
    Dio dio = new Dio(options);
    // 生成oss的路径和文件名我这里目前设置的是moment/20201229/test.mp4
    String pathName = '$rootDir/${getDate()}/${getRandom(12)}.${fileType == null ? getFileType(file.path) : fileType}';

    // 请求参数的form对象
    FormData data = new FormData.fromMap({
      'key': pathName,
      'policy': getSplicyBase64(policyText),
      'OSSAccessKeyId': ossAccessKeyId,
      'success_action_status': '200', //让服务端返回200,不然,默认会返回204
      'signature': signature,
      'contentType': 'multipart/form-data',
      'file': MultipartFile.fromFileSync(file.path),
    });

    Response response;
    CancelToken uploadCancelToken = CancelToken();
    callback ?? callback(uploadCancelToken);

    try {
      // 发送请求
      response = await dio.post(url, data: data, cancelToken: uploadCancelToken, onSendProgress: (int count, int data) {
        onSendProgress(count, data);
      });
      // 成功后返回文件访问路径
      return '$url/$pathName';
    } catch(e) {
      throw(e.message);
    }

  }

  /*
  * 生成固定长度的随机字符串
  * */
  static String getRandom(int num) {
    String alphabet = 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM';
    String left = '';
    for (var i = 0; i < num; i++) {
//    right = right + (min + (Random().nextInt(max - min))).toString();
      left = left + alphabet[Random().nextInt(alphabet.length)];
    }
    return left;
  }
  /*
  * 根据图片本地路径获取图片名称
  * */
  static String getImageNameByPath(String filePath) {
    // ignore: null_aware_before_operator
    return filePath?.substring(filePath?.lastIndexOf("/")+1,filePath?.length);
  }
  /**
   * 获取文件类型
   */
  static String getFileType(String path) {
    print(path);
    List<String> array = path.split('.');
    return array[array.length -1];
  }
  /// 获取日期
  static String getDate() {
    DateTime now = DateTime.now();
    return '${now.year}${now.month}${now.day}';
  }

  // 获取plice的base64
  static getSplicyBase64(String policyText) {
    //进行utf8编码
    List<int> policyText_utf8 = utf8.encode(policyText);
    //进行base64编码
    String policy_base64 = base64.encode(policyText_utf8);
    return policy_base64;
  }

  /// 获取签名
  static String getSignature(String policyText) {
    //进行utf8编码
    List<int> policyText_utf8 = utf8.encode(policyText);
    //进行base64编码
    String policy_base64 = base64.encode(policyText_utf8);
    //再次进行utf8编码
    List<int> policy = utf8.encode(policy_base64);
    //进行utf8 编码
    List<int> key = utf8.encode(ossAccessKeySecret);
    //通过hmac,使用sha1进行加密
    List<int> signature_pre = Hmac(sha1, key).convert(policy).bytes;
    //最后一步,将上述所得进行base64 编码
    String signature = base64.encode(signature_pre);
    return signature;
  }
}

调用上传的例子

其他参事自己根据自己情况上传

Future<String> uploadFile(File file, { Function onSendProgress, Function callback}) async {
  final String url = await UploadOss.upload(file: file, onSendProgress: onSendProgress, callback: callback);
  return url;
}

另一种方法

目前阿里没有针对Flutter有官方SDK可集成, 但是有人对Flutter的上传有封装库https://pub.dev/packages/aly_oss#-example-tab-, 所以我们只能通过post提交PostObject的形式来上传;

准备工作:

1、获取OSS凭证地址(your oss_sts_server), 通知get直接获取static String ossServerUrl = 'http://.../sts-server/sts.php';

2、上传的存储地址(桶名):static String ossEndPointCdn = '<your endpointcdn>';

// 通过ossServerUrl直接get获取到如下数据
{
        "StatusCode": 200,
          "AccessKeyId": "STS.NSsrKZes4cqm.....",
          "AccessKeySecret": "7eGnLZaEFsRCGYJAnrtdE9n.....",
          "Expiration": "2020-04-08T03:44:21Z",
          "SecurityToken": "CAISlQJ1q6Ft5B2y....."
  }

//表单需要的参数: AccessKeyId、AccessKeySecret、SecurityToken;
FormData formdata = new FormData.from({
        //文件名,随意
        'Filename': OssUtil.instance.getImageName(filePath),
        //"可以填写文件夹名(对应于oss服务中的文件夹)/" + fileName
        'key': uploadName,//上传后的文件名
        'policy': OssUtil.policy,
        //Bucket 拥有者的AccessKeyId。
        'OSSAccessKeyId': data['AccessKeyId'],
        //让服务端返回200,不然,默认会返回204
        'success_action_status': '200',
        'signature': OssUtil.instance.getSignature(data['AccessKeySecret']),
        //临时用户授权时必须,需要携带后台返回的security-token
        'x-oss-security-token': data['SecurityToken'],
        'file': new UploadFileInfo(
            file, OssUtil.instance.getImageNameByPath(filePath))
        //必须放在参数最后
   });
//然后通过存储地址直接把表单(formdata)上传上去;
Dio dio=Dio();
dio.options.responseType=ResponseType.plain;
Response response=awaitdio.post(<ossEndPointCdn>,data:formData);
......

tips: 上传成功后图片地址 imageUrl = ossEndPointCdn + '/' + uploadName;

给一个工具类

import 'dart:convert';
import 'package:crypto/crypto.dart';
import 'dart:math';

class OssUtil {
 获取
  //验证文本域
  static String _policyText =
      '{"expiration": "2069-05-22T03:15:00.000Z","conditions": [["content-length-range", 0, 1048576000]]}';//UTC时间+8=北京时间

  //进行utf8编码
  // ignore: non_constant_identifier_names
  static List<int> _policyText_utf8 = utf8.encode(_policyText);
  //进行base64编码
  static String policy= base64.encode(_policyText_utf8);

  //再次进行utf8编码
  // ignore: non_constant_identifier_names
  static List<int> _policy_utf8 = utf8.encode(policy);

  // 工厂模式
  factory OssUtil() => _getInstance();

  static OssUtil get instance => _getInstance();
  static OssUtil _instance;

  OssUtil._internal();

  static OssUtil _getInstance() {
    if (_instance == null) {
      _instance = new OssUtil._internal();
    }
    return _instance;
  }

  /*
  *获取signature签名参数
  */
  String getSignature(String _accessKeySecret){
    //进行utf8 编码
    // ignore: non_constant_identifier_names
    List<int> AccessKeySecretUtf8 = utf8.encode(_accessKeySecret);
    //通过hmac,使用sha1进行加密
    List<int> signaturePre = new Hmac(sha1, AccessKeySecretUtf8).convert(_policy_utf8).bytes;
    //最后一步,将上述所得进行base64 编码
    String signature = base64.encode(signaturePre);
    return signature;
  }

  // ignore: slash_for_doc_comments
  /**
   * 生成上传上传图片的名称 ,获得的格式:photo/20171027175940_oCiobK
   * 可以定义上传的路径uploadPath(Oss中保存文件夹的名称)
   * @param uploadPath 上传的路径 如:/photo
   * @return photo/20171027175940_oCiobK
   */
  String getImageUploadName(String uploadPath,String filePath) {
    String imageMame = "";
    var timestamp = new DateTime.now().millisecondsSinceEpoch;
    imageMame =timestamp.toString()+"_"+getRandom(6);
    if(uploadPath!=null&&uploadPath.isNotEmpty){
      imageMame=uploadPath+"/"+imageMame;
    }
    String imageType=filePath?.substring(filePath?.lastIndexOf("."),filePath?.length);
    return imageMame+imageType;
  }

  String getImageName(String filePath) {
    String imageMame = "";
    var timestamp = new DateTime.now().millisecondsSinceEpoch;
    imageMame =timestamp.toString()+"_"+getRandom(6);
    String imageType=filePath?.substring(filePath?.lastIndexOf("."),filePath?.length);
    return imageMame+imageType;
  }

  /*
  * 生成固定长度的随机字符串
  * */
  String getRandom(int num) {
    String alphabet = 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM';
    String left = '';
    for (var i = 0; i < num; i++) {
//    right = right + (min + (Random().nextInt(max - min))).toString();
      left = left + alphabet[Random().nextInt(alphabet.length)];
    }
    return left;
  }

  /*
  * 根据图片本地路径获取图片名称
  * */
  String getImageNameByPath(String filePath) {
    // ignore: null_aware_before_operator
    return filePath?.substring(filePath?.lastIndexOf("/")+1,filePath?.length);
  }
}

以上就是flutter直接上传文件到阿里云oss的实现步骤的详细内容,更多关于flutter 上传文件到阿里云oss的资料请关注我们其它相关文章!

(0)

相关推荐

  • Flutter 超实用简单菜单弹出框 PopupMenuButton功能

    相信在实际开发过程当中,肯定少不了这样的功能: 点击 AppBar 右上角的按钮,弹出一个菜单供用户选择. 幸运的是,Flutter 提供给我们了一个 Widget,直接就能实现如上的效果. PopupMenuButton 还是老规矩,先看官方的说明: Displays a menu when pressed and calls onSelected [1] when the menu is dismissed because an item was selected. The value pa

  • Flutter中http请求抓包的完美解决方案

    前言 前阵子有同学反馈Flutter中的http请求无法通过fiddler抓包,作者喜欢使用Charles抓包工具,于是抽时间写了个小demo测试了一下,结论是在手机上设置代理,Charles确实抓不到请求数据包.于是对该问题进行了分析: 确定使用的是http发起的get请求,理论上http协议应该可以被Charles抓到包的,如果没有抓到包,那可能是没有走代理,于是乎通过将笔记本连接的wifi断开测试了一下手机上APP发起http请求,发现请求成功,证实确实没有走代理: 为什么http请求没有

  • Flutter进阶之实现动画效果(一)

    上一篇文章我们了解了Flutter的动画基础,这一篇文章我们就来实现一个图表的动画效果. 首先,我们需要创建一个新项目myapp,然后把main.dart的内容替换成下面的代码 import 'package:flutter/material.dart'; import 'dart:math'; void main() { runApp(new MyApp()); } class MyApp extends StatelessWidget { @override Widget build(Bui

  • Flutter实现页面切换后保持原页面状态的3种方法

    前言: 在Flutter应用中,导航栏切换页面后默认情况下会丢失原页面状态,即每次进入页面时都会重新初始化状态,如果在initState中打印日志,会发现每次进入时都会输出,显然这样增加了额外的开销,并且带来了不好的用户体验. 在正文之前,先看一些常见的App导航,以喜马拉雅FM为例: 它拥有一个固定的底部导航以及首页的顶部导航,可以看到不管是点击底部导航切换页面还是在首页左右侧滑切换页面,之前的页面状态都是始终维持的,下面就具体介绍下如何在flutter中实现类似喜马拉雅的导航效果 第一步:实

  • flutter Container容器实现圆角边框

    本文实例为大家分享了flutter Container容器实现圆角边框的具体代码,供大家参考,具体内容如下 在这里使用 Container 容器来实现圆角矩形边框效果 1 圆角矩形边框 Container( margin: EdgeInsets.only(left: 40, top: 40), //设置 child 居中 alignment: Alignment(0, 0), height: 50, width: 300, //边框设置 decoration: new BoxDecoration

  • 你必须掌握在Flutter中添加资源文件的方法

    在 Flutter 中,需要在根目录下的 pubspec.yaml 文件中配置资源的路径,资源才能被打包使用.现在,看看如何配置资源吧. 1. 添加图片资源文件 1.1 添加本地图片资源 flutter: assets: // 表示引入根目录下的 images 文件夹下的所有资源文件 - images/ // 只添加 images/ 下的 pci.png - images/pci.png 注意缩进!本地文件夹内的资源可以选择导入整个文件夹,或者只导入指定文件.使用:Image.asset("im

  • Flutter持久化存储之数据库存储(sqflite)详解

    前言 数据库存储是我们常用的存储方式之一,对大批量数据有增.删.改.查操作需求时,我们就会想到使用数据库,Flutter中提供了一个sqflite插件供我们用于大量数据执行CRUD操作.本篇我们就来一起学习sqflite的使用. sqflite是一款轻量级的关系型数据库,类似SQLite. 在Flutter平台我们使用sqflite库来同时支持Android 和iOS. sqflite使用 引入插件 在pubspec.yaml文件中添加path_provider插件,最新版本为1.0.0,如下:

  • Flutter中如何加载并预览本地的html文件的方法

    直接进入主题,大概步骤如下 在 assets 创建需要访问 html 文件,如下 这里创建一个files文件夹,专门来放这些静态 html 文件. 在 pubspec.yaml 中配置访问位置 assets: - assets/images/ - assets/files/ 在 pubspec.yaml 添加 webview_flutter 插件依赖 webview_flutter: ^0.3.15+1 // 具体版本请查看官网 进入实际的代码操作 import 'dart:convert';

  • 详解Flutter WebView与JS互相调用简易指南

    本文采用Flutter官方WebView插件:https://pub.dartlang.org/packages/webview_flutter WebView与JS互相调用是一个刚需,但是貌似现在大家写的文章讲的都不是很清楚,我这个简易指南简单粗暴地分为两部分:JS调用Flutter和Flutter调用JS,拒绝花里胡哨,保证一看就懂,一学就会. 开始之前先简单了解一下官方WebView所包含的API: onWebViewCreated:在WebView创建完成后调用,只会被调用一次: ini

  • flutter直接上传文件到阿里云oss

    代码实现 以下是我写的一个上传oss的类,只需要替换ossAccessKeyId, ossAccessKeySecret, bucket, url, expiration这几个参数就可以直接实现上传 import 'dart:convert'; import 'dart:io'; import 'dart:math'; import 'package:crypto/crypto.dart'; import 'package:dio/dio.dart'; class UploadOss { sta

  • 微信小程序上传文件到阿里OSS教程

    前言 (一)开通OSS服务与新建Bucket 开通OSS服务这里省略,新建bucket. (二)设置Bucket属性,后台配置域名 上传文件访问域名 这里我们要在小程序后台配置上传域名(上面的域名是我自己的申请的,后台配置的是公司的的域名,使用的时候你们用一套东西即可). 下图是bucket管理,这里可以新建文件的保存路径,域名管理. (三)服务端签名直传 点击查看文档 这里就不多做介绍了,这是上传文件到oss需要的参数,这些数据可以从后台获取. { "accessid": "

  • yii2.0整合阿里云oss上传单个文件的示例

    上一篇文章已经介绍了如何整合阿里云oss,这一篇主要介绍上传文件到阿里云oss. 主要思路:首先文件要上传到服务器,然后把服务器里边的文件传到阿里云oss,成功以后就把文件信息写入数据库,失败了就删除服务器的文件. 主要步骤: 0 介绍几个oss的概念. accessKeyId     ==>> 可以理解为访问阿里云oss的账号 accessKeySecret ==>> 可以理解为访问阿里云oss的密码 bucket          ==>> 可以理解为文件在保存的根

  • SpringBoot整合阿里云OSS对象存储服务的实现

    今天来整合一下SpringBoot和阿里云OSS对象存储服务. 一.配置OSS服务 先在阿里云开通对象存储服务,拿到AccessKeyId.AccessKeySecret. 创建你的bucket(存储空间),相当于一个一个的文件夹目录.按业务需求分类存储你的文件,图片,音频,app包等等.创建bucket是要选择该bucket的权限,私有,公共读,公共读写,按需求选择.创建bucket时对应的endpoint要记住,上传文件需要用到. 可以配置bucket的生命周期,比如说某些文件有过期时间的,

  • Java下载https文件并上传阿里云oss服务器

    这篇文章主要介绍了Java下载https文件并上传到阿里云oss服务器,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 今天做了一个从Https链接中下载音频并且上传到OSS服务器,记录一下希望大家也少走弯路. 一共两个类: 1 .实现自己的证书信任管理器类 /** * @author mazhq * @Title: X509TrustUtiil * @ProjectName: zeus * @Description: 证书信任管理器类 * @d

  • springboot操作阿里云OSS实现文件上传,下载,删除功能

    参考资料:Java操作阿里云OSS操作官方文档 学会看文档,并实际运用也是一种习惯和技能 下面就来简单入门一下,用当下比较热门的Springboot 去操作阿里云OSS文件存储. 1.需求 (没踩过下面的坑的小伙伴可以直接跳过这一章节) 问题简述 首先,我在之前自己做一些开源小项目案例中遇到一些文件上传下载的问题,比如在本机文件上传和下载都可以正常使用,通过将文件上传到Springboot项目的根目录下,按日期分文件夹,文件访问也很方便,可以直接返回文件相对路径地址,并直接可以访问. 问题 然而

  • springboot整合阿里云oss上传的方法示例

    OSS申请和配置 1. 注册登录 输入网址:https://www.aliyun.com/product/oss 如果没有账号点击免费注册,然后登录. 2.开通以及配置 点击立即开通 进入管理控制台 第一次使用会出现引导,按引导点击"我知道了",然后点击创建Bucket. 如果没有存储包或流量包点击购买. 点击确定,返回主页面,出现该页面,点击我知道了 将EndPoint记录下来,方便后期添加到我们项目的配置文件中 创建 AccessKeyID 和 AccessKeySecret 点击

  • Thinkphp整合阿里云OSS图片上传实例代码

    Thinkphp3.2整合阿里云OSS图片上传实例,图片上传至OSS可减少服务器压力,节省宽带,安全又稳定,阿里云OSS对于做负载均衡非常方便,不用传到各个服务器了 首先引入阿里云OSS类库 <?php namespace Home\Controller; use Think\Controller; use OSS\Core\OssException; vendor('aliyun.autoload'); 上传图片自己写,上传成功到阿里云后,删除临时文件 function aliyun() {

  • Python使用百度API上传文件到百度网盘代码分享

    关于如何获取 access_token 这个可以自己查百度开放的OAuth 2.0 的 API.这里不做介绍. 第三方 Python 库 poster 复制代码 代码如下: # coding:UTF-8 import urllib import urllib2 __author__ = 'Administrator' from poster.encode import multipart_encode from poster.streaminghttp import register_opene

  • java实现上传文件到oss(阿里云)功能示例

    本文实例讲述了java实现上传文件到oss(阿里云)功能.分享给大家供大家参考,具体如下: 做这个功能之前我们需要导入阿里云OSS官方提供的工具包 aliyun-sdk-oss-2.5.0.jar 这个文件 如果有最新版的话就下载最新版 aliyun.upload.AliyunConfig package aliyun.upload; public final class AliyunConfig { //你的oss所在域,要加http:// 不明白可以对照你的文件引用地址 public sta

随机推荐