阿里云文件上传之前一直是利用服务端上传,但一直存在上传不稳固题目,三兆以上的文件上传经常出现上传超时题目.究其原因客户端将文件上传到业务服务器,然后业务服务器将文件上传到OSS。在这个过程中,一份数据必要在网络上传输两次,会造成网络资源的浪费,增长服务端的资源开销。为了办理这一题目,可以在客户端直连OSS来完成文件上传,无需颠末业务服务器中转。下面简单记录一下实现客户端直传的实战过程,本文技能栈:前端vue+后端springbooot.
实现客户端直传必要办理两个题目跨域和oss认证授权信息安全性题目(客户端相对服务端不安全)
首先跨域题目,只必要从oss控制台配置即可,配置规则如下:

无需从代码侧配置(会出现sts权限认证失败题目)
参考文档: 跨域配置
授权信息处理的思路是服务端提供临时授权信息给到客户端.下面是服务端代码:
- public static void main(String[] args) {
- // 工程代码泄露可能会导致 AccessKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考。
- // 建议使用更安全的 STS 方式,更多鉴权访问方式请参见:https://help.aliyun.com/document_detail/378657.html。
- com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
- // 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。
- .setAccessKeyId("ALIBABA_CLOUD_ACCESS_KEY_ID")
- // 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
- .setAccessKeySecret("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
- // Endpoint 请参考 https://api.aliyun.com/product/Sts
- config.endpoint = "stsEndpoint";
- com.aliyun.sts20150401.Client client = new Client(config);
- com.aliyun.sts20150401.models.AssumeRoleRequest assumeRoleRequest = new com.aliyun.sts20150401.models.AssumeRoleRequest()
- .setRoleArn("配置角色权限")
- .setRoleSessionName("自定义会话名称");
- com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
- try {
- com.aliyun.sts20150401.models.AssumeRoleResponse resp = client.assumeRoleWithOptions(assumeRoleRequest, runtime);
- System.out.println("打印内容:"+com.aliyun.teautil.Common.toJSONString(resp));
- } catch (TeaException error) {
- // 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
- // 错误 message
- System.out.println(error.getMessage());
- // 诊断地址
- System.out.println(error.getData().get("Recommend"));
- com.aliyun.teautil.Common.assertAsString(error.message);
- } catch (Exception _error) {
- TeaException error = new TeaException(_error.getMessage(), _error);
- // 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
- // 错误 message
- System.out.println(error.getMessage());
- // 诊断地址
- System.out.println(error.getData().get("Recommend"));
- com.aliyun.teautil.Common.assertAsString(error.message);
- }
- }
复制代码 必要的依靠:
- <dependency>
- <groupId>com.aliyun</groupId>
- <artifactId>sts20150401</artifactId>
- <version>1.1.4</version>
- </dependency>
- <dependency>
- <groupId>com.aliyun</groupId>
- <artifactId>tea-openapi</artifactId>
- <version>0.3.2</version>
- </dependency>
- <dependency>
- <groupId>com.aliyun</groupId>
- <artifactId>tea-console</artifactId>
- <version>0.0.1</version>
- </dependency>
- <dependency>
- <groupId>com.aliyun</groupId>
- <artifactId>tea-util</artifactId>
- <version>0.2.21</version>
- </dependency>
复制代码 上面给出代码中必要的配置信息参考官方文档针对于客户端上传创建用户并分配权限. 客户端直传创建RAM用户并授权
vue项目中文件上传核心逻辑:
- const OSS = require('ali-oss');
- const client = new OSS({
- // 将<YOUR_BUCKET>设置为OSS Bucket名称。
- bucket: "<YOUR_BUCKET>",
- // 将<YOUR_REGION>设置为OSS Bucket所在地域,例如oss-cn-hangzhou。
- region: "<YOUR_REGION>",
- accessKeyId: "服务端获取",
- accessKeySecret: "服务端获取",
- stsToken: "服务端获取"
- });
-
- const result = client.put('qrCode/img/'+file.name, file);
- console.log("beforeAvatarUpload:",result);
复制代码 上传乐成后文件访问路径默认就是配置的oss域名+文件存储路径.
增补:断点上传,返回上传进度可配合实现进度条
- // 断点续传,阿里云客服提供,可配合实现进度条
- let savedCpt;
- const result = client.multipartUpload('qrCode/voice/' + fileInfo.name, fileInfo, {
- checkpoint: savedCpt,
- progress: function(p, cpt, res) {
- //progress is generator
- console.log("p:", p);
- this.uploadPercentage = p * 100
- console.log("this.uploadPercentage:", this.uploadPercentage)
- console.log("cpt:", cpt);
- console.log("res:", res);
- }
- });
复制代码 增补:现实场景中会出现连接超时题目,必要举行优化,优化方式就是客户端上传方式优化,由简单上传变更为分片上传.
分片上传场景:
大文件加快上传
当文件大小超过5 GB时,利用分片上传可实现并行上传多个Part以加快上传速度。
网络情况较差
网络情况较差时,建议利用分片上传。当出现上传失败的时候,您仅需重传失败的Part。
文件大小不确定
可以在必要上传的文件大小还不确定的情况下开始上传,这种场景在视频监控等行业应用中比较常见。
分片上传相关代码:
- const options = {
- // 获取分片上传进度、断点和返回值。
- progress: (p, cpt, res) => {
- console.log("上传进度:", p);
- },
- // 设置并发上传的分片数量。
- // parallel: 4,
- // 设置分片大小。默认值为1 MB,最小值为100 KB。
- partSize: 1024 * 1024,
- timeout: 120000
- };
- await this.client.multipartUpload("oss路径+文件名", file, options).then(res => {
- console.log("res:", res)
- }).catch(err => {
- console.log(2222, err)
- throw new Error("操作失败,请重试!");
- })
复制代码 阿里云官方客户端多文件上传demo
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |