前言
在 Flutter Web 在《一起漫部》的性能优化摸索与实际 一文中,
在做加载优化时须要实现资源文件cdn化,意味着要将资源文件上传到腾讯的COS或者阿里的OSS这样的第三方对象存储服务器。 目前公司应用的是腾讯的对象存储(COS),本来想用官网提供的SDK去实现资源上传性能,然而官网并没有提供Dart版本的SDK, 去pub.dev
搜了下对于cos的相干插件,也没有找到性能绝对欠缺的插件,于是便打算手写一个Dart版本对象存储(COS)插件。
简介
在官网提供的API性能过于丰盛和工夫无限的状况下,只实现了局部性能:
- 反对
Bucket
接口的基本操作,减少、删除、查问存储桶等 - 反对
Bucket
接口的访问控制(acl) - 反对
Bucket
接口的跨域资源共享(cors) - 反对
Bucket
接口的防盗链(referer) - 反对
Object
接口的基本操作,上传、删除、查问存储对象等 - 反对
Object
接口的访问控制(acl)
构造
工程次要包含示例(example)、外围代码(lib)和单元测试(test)三局部
├── CHANGELOG.md├── LICENSE├── README.md├── analysis_options.yaml├── example // 示例├── lib // 外围代码│ ├── src│ │ ├── api│ │ ├── client│ │ ├── model│ │ └── src.dart│ └── tencent_cos_plus.dart├── pubspec.lock├── pubspec.yaml├── tencent_cos_plus.iml└── test // 单元测试
示例
示例目前仅包含tencent_cos_plus_example.dart
文件,次要是介绍如何应用插件,包含初始化配置、存储桶Api调用和存储对象 Api调用。
├── example│ └── tencent_cos_plus_example.dart
外围代码
外围代码(lib)局部由client
、api
和model
三层形成:
client
层封装了http申请和接口签名性能api
层实现了存储桶(bucket)和存储对象(object)局部api的调用model
层负责xml数据和实体对象的解析
├── api│ ├── api.dart│ ├── cos_abstract_api.dart│ ├── cos_api_factory.dart│ ├── cos_api_mixin.dart│ ├── cos_bucket_api.dart│ └── cos_object_api.dart├── client│ ├── client.dart│ └── cos_client.dart├── model│ ├── common│ │ ├── cos_access_control_policy.dart│ │ ├── cos_common.dart│ │ ├── cos_config.dart│ │ ├── cos_cors_configuration.dart│ │ ├── cos_exception.dart│ │ └── cos_referer_configuration.dart│ ├── model.dart│ ├── request│ │ ├── cos_bucket_acl_header.dart│ │ ├── cos_create_bucket_configuration.dart│ │ ├── cos_delete.dart│ │ ├── cos_get_object.dart│ │ └── cos_restore_request.dart│ └── response│ ├── cos_copy_object_result.dart│ ├── cos_delete_result.dart│ ├── cos_list_all_my_buckets_result.dart│ ├── cos_list_bucket_result.dart│ └── cos_list_versions_result.dart
单元测试
单元测试包含cos_bucket_api_test.dart
和cos_object_api_test.dart
两个文件,次要是笼罩了存储桶(bucket)
和存储对象(object)局部api的单元测试
└── test ├── cos_bucket_api_test.dart └── cos_object_api_test.dart
应用阐明
对于如何应用,请参考 README
碰到的问题
在开发过程中,实现须要提交xml数据的接口时,呈现签名不匹配的问题。
<?xml version='1.0' encoding='utf-8' ?><Error> <Code>SignatureDoesNotMatch</Code> <Message>The Signature you specified is invalid.</Message> <StringToSign>sha11666158568;1666218568488ab174d5f7a6ec0966aeeb82600e185114d7d1</StringToSign> <FormatString>put/cors=content-length=454&content-md5=DfuiC7IOBwIeiVanWPG%2FKg%3D%3D&content-type=application%2Fxml%3B%20charset%3Dutf-8&date=Wed%2C%2019%20Oct%202022%2005%3A49%3A28%20GMT&host=test-app-1251021022.cos.ap-guangzhou.myqcloud.com</FormatString> <Resource>/</Resource> <RequestId>NjM0ZjhmZThfNDgzNjQwMGJfMTMwZWFfNDhmODEyZg==</RequestId> <TraceId>OGVmYzZiMmQzYjA2OWNhODk0NTRkMTBiOWVmMDAxODc0OWRkZjk0ZDM1NmI1M2E2MTRlY2MzZDhmNmI5MWI1OTBjYzE2MjAxN2M1MzJiOTdkZjMxMDVlYTZjN2FiMmI0MjFmNzE4ZjVmM2M0ZTcxNjYwMmQ3N2QzYjA3NzYyNmM=</TraceId></Error>
呈现这个问题后,先是确认了签名文档提供的签名规定是否统一,而后应用 COS 签名工具
去验证签名后果是否统一,发现在都没有问题。最初通过api接口返回的错误信息,发现参加签名的content-type
和提交给api的content-type
不统一,导致签名不匹配。
通过断点调试,排查到是应用的 http 插件造成的,在设置body
时如果content-type
没有charset
时会赋值默认的charset
,问题找到了。
其它
- 目前有余的是上传文件和下载文件时,没有进度的回调
总结
整个插件实现起来不难,次要须要花工夫浏览腾讯对象存储(COS)文档,依据Api文档进行封装和测试,这里开源进去给须要的人提供帮忙。
- pub: tencent_cos_plus
- git: tencent_cos_plus