前端如何进行单文件上传云服务存储

在日常的开发过程中,我相信大家肯定会碰到很多的文件上传需求,例如流程中的附件,设置头像图片等等内容,并且上传的文件,为了前端页面的加载性能,一般也都会选择将文件上传至云服务存储当中去,之后直接使用文件的 cdn 路径来访问 。那么问题来了,对于文件如何上传到云服务存储当中去大家是否了解呢?上传流程有遇到什么困难吗,所以这篇文章也借着我们团队遇到的一些问题,跟大家交流一下云服务文件存储当中的一些问题与解决方式 。
目前常用的上传方式后端上传不知道大家日常使用的上传方式是否和我们团队一致,之前上传文件方案中,我司后端团队会提供一个后端上传服务接口,前端直接使用这个接口进行文件上传,后端接受到完整文件后,会再通过调用云文件服务提供的后端 JAVA SDK 进行文件上传

前端如何进行单文件上传云服务存储

文章插图
这个方案的优缺点
优点:前端所有使用的上传接口统一,前端统一对接公司内部的上传服务,后端上传服务再去对接各个不同的云存储服务厂家,保证文件上传
缺点:后端服务需要接受所有的文件上传的流量,然后再次进行上传,服务器压力比较大 。
基于上面提到的缺点,在经历过服务器压力过大,导致几次大文件上传失败、各种外地网络延迟导致超时故障之后,痛定思痛,决定要重新调整上传的方式 。
前端上传既然后端服务上传需要走流程传输导致资源压力过大,那是否可以可以将压力转移到用户侧,使用用户的浏览器直连云存储服务进行上传呢?答案是当然可以,不然也就没有本文了 。
在翻阅了几个不同的云服务的上传文档后发现,目前主流常用的前端上传方案会分为两种方式:
  1. 前端调用各大云服务的 JavaScript SDK 进行上传
  1. 优点:无需后端服务介入,直接调用各个云服务 SDK 方法使用即可
  2. 缺点:前端需要获取各个云服务的 AK (AccessKey ID),SK (AccessKey Secret) 等账号信息,并且会暴漏在代码中,并且各个云服务场景会有对应的 SDK 以及调用方式,全部做了集成的话,包的体积可能不可控,并且有些云服务商,没有提供前端使用的SDK 。
  1. 云服务会提供临时授权的 URL,前端可以直接通过这个授权 URL 访问云服务,进行文件上传
  2. 优点:前端不需要获取云服务的 AK (AccessKey ID),SK (AccessKey Secret) 信息,统一由后端接口提供对应上传所需的请求地址,数据格式即可,前端通过一个接口获取这些信息后,调用上传即可
  3. 缺点:各家云服务上传所需的数据格式都不相同,前端需要调研,解析这个数据格式
上传示例下面以大家常用的阿里云举例
SDK上传webpack打包类型项目,可以先通过 npm install ali-oss 安装 SDK,以下为上传数据到 examplebucket 中 exampledir 目录下的exampleobject.txt 文件的代码示例
const OSS = require('ali-oss');const client = new OSS({// 以下为初始化参数region: 'yourRegion',// 从 STS 服务获取的临时访问密钥(AccessKey ID和AccessKey Secret) 。accessKeyId: 'yourAccessKeyId',accessKeySecret: 'yourAccessKeySecret',// 从STS服务获取的安全令牌(SecurityToken) 。stsToken: 'yourSecurityToken',// 填写 Bucket 名称(可以简单理解为,你上传不同文件到不同的文件夹命名) 。bucket: 'examplebucket'});// 从输入框获取 file 对象,例如 <input type="file" id="file" /> 。let data;// 创建并填写 Blob 数据 。//const data = https://www.isolves.com/it/cxkf/qd/2023-06-01/new Blob(['Hello OSS']);// 创建并填写 OSS Buffer内容 。//const data = new OSS.Buffer(['Hello OSS']);const upload = document.getElementById("upload");const headers = {// 以下为上传时可以设置的一些 header 数据,不同云服务需要的不同,具体参考各个版本文档// 'Content-Type': 'text/html', // 指定上传文件的类型 。// 'Cache-Control': 'no-cache',// 指定该 Object 被下载时网页的缓存行为 。// 'Content-Disposition': 'oss_download.txt',// 指定该 Object 被下载时的名称 。// 'Content-Encoding': 'UTF-8',// 指定该 Object 被下载时的内容编码格式 。// 'Expires': 'Wed, 08 Jul 2022 16:57:01 GMT',// 指定过期时间 。// 'x-oss-storage-class': 'Standard',// 指定 Object 的存储类型 。// 'x-oss-object-acl': 'private',// 指定 Object 的访问权限 。};async function putObject(data) {try {// 填写Object完整路径 。Object 完整路径中不能包含 Bucket 名称 。// 您可以通过自定义文件名(例如 exampleobject.txt )或文件完整路径(例如 exampledir/exampleobject.txt )的形式实现将数据上传到当前 Bucket 或 Bucket 中的指定目录 。// data 对象可以自定义为 file 对象、Blob 数据或者 OSS Buffer 。const result = awAIt client.put("exampledir/exampleobject.txt",data//{headers});console.log(result);} catch (e) {console.log(e);}}upload.addEventListener("click", () => {data = document.getElementById("file").files[0];putObject(data);});


推荐阅读