前端直传ali-oss

在项目里有时候会碰到比如上传文件相关的,一般都是后端提供个接口,然后我们上传的时候后端再传到阿里OSS或者其他服务商的对象存储,然后把最终的url拿到存起来或者返回给前端,这种方式其实在上传图片的频率不高的业务场景中可能并无大碍,但是如果有频繁的上传文件的场景,服务器压力较大,那就要介绍一种解决方法,前端直传ali-oss。

1.ali-oss npm包

提供了非常多的api,可自行到www.npmjs.com/package/ali... 查看

2.介绍前端直传file的几种方式

put

特点

  • 适用于小文件和普通文件上传。
  • 使用 put 方法上传文件时,整个文件会一次性上传到 OSS,如果文件较小(通常小于 100MB),那么这种方式是最简单和高效的。
  • 如果上传的文件较大(通常大于 100MB),使用 put 方法可能会导致网络不稳定或服务器超时,因此不适合大文件上传,可能会出现上传失败或上传时间过长的情况。

参数:一般接收两个参数, 文件路径文件file`

引入ali-oss

bash 复制代码
#安装
npm install ali-oss --save

需要实例化oss

javascript 复制代码
import OSS from "ali-oss"
或通过cdn的方式引入
php 复制代码
const client = new OSS({
            // 将<your_bucket>设置为OSS Bucket名称。
            bucket: "<your_bucket>",
        
            //oss中项目的accessKeyId 和 accessKeySecret
            accessKeyId: credentials.AccessKeyId,
            accessKeySecret: credentials.AccessKeySecret,
            //从STS服务获取的安全令牌(SecurityToken)
            stsToken: credentials.SecurityToken,
            secure: true, //是否启用HTTPS,https true   http false
            endpoint: 'oss-cn-hangzhou.aliyuncs.com' ,//地域节点 ==》外网访问
            // 将<your_region>设置为OSS Bucket所在地域,例如region: 'oss-cn-hangzhou'。
            region: "oss-cn-hangzhou",
          });

如何获取accessKeyId 和 accessKeySecret

1、点击概览 --- AccessKey

oss控制台官网链接:oss.console.aliyun.com/overview

2、出现下图,选择开始使用子用户Access Key
3、填写用户名,并点击确定
4、这时会给你的手机发送验证码确认是否是本人操作,填写验证码后,用户创建成功
5、创建完毕后,会出现下面的页面,我们可以看到创建的accessKeyIdAccessKeySecret
6、为新创建的用户添加权限

OSS官网也提供了一份关于put去上传文件的demo

xml 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>上传文件到OSS</title>
    <script src="https://gosspublic.alicdn.com/aliyun-oss-sdk-6.17.0.min.js"></script>
  </head>
  <body>
    <div class="container">
      <form>
        <div class="mb-3">
          <label for="file" class="form-label">选择文件</label>
          <input
            type="file"
            class="form-control"
            id="file"
            name="file"
            required
          />
        </div>
        <button type="submit" class="btn btn-primary">上传</button>
      </form>
    </div>
    <script type="text/javascript">
      let credentials = null;
      const form = document.querySelector("form");
      form.addEventListener("submit", async (event) => {
        event.preventDefault();
        try {
          // 临时凭证过期时,才重新获取,减少对 sts 服务的调用
          if (isCredentialsExpired(credentials)) {
            const response = await fetch("/get_sts_token_for_oss_upload", {
              method: "GET",
            });
            if (!response.ok) {
              throw new Error("无法获取STS临时凭证");
            }
            credentials = await response.json();
          }
          const client = new OSS({
            // 将<your_bucket>设置为OSS Bucket名称。
            bucket: "<your_bucket>",
            // 将<your_region>设置为OSS Bucket所在地域,例如region: 'oss-cn-hangzhou'。
            region: "oss-<your_region>",
            accessKeyId: credentials.AccessKeyId,
            accessKeySecret: credentials.AccessKeySecret,
            stsToken: credentials.SecurityToken,
          });
          const fileInput = document.querySelector("#file");
          const file = fileInput.files[0];
          const result = await client.put(file.name, file);
          console.log(result);
          alert("文件已上传");
        } catch (error) {
          console.error(error);
          if (error.code === "Forbidden" || error.code === 403) {
            alert("缺少OSS操作权限");
          } else {
            alert("存在跨域问题,请确认OSS Bucket正确配置了CORS。");
          }
        }
      });
      /**
       * 判断临时凭证是否到期。
       **/
      function isCredentialsExpired(credentials) {
        if (!credentials) {
          return true;
        }
        const expireDate = new Date(credentials.Expiration);
        const now = new Date();
        // 如果有效期不足一分钟,视为过期。
        return expireDate.getTime() - now.getTime() <= 60000;
      }
    </script>
  </body>
</html>
​

multipartUpload

特点:

  • 适用于大文件和断点续传。
  • 使用 multipartUpload 方法时,文件会被分割成多个部分(即分片),每个分片独立上传到 OSS,并在 OSS 上重新组装成完整的文件。
  • 分片上传可以提高上传效率,避免网络不稳定或服务器超时导致的上传失败,同时也支持断点续传,即使网络中断或上传过程中出现其他问题,也可以在中断处继续上传。

参数: 1. 文件的完整上传路径 1.文件

可以看出回调中提供了一些关于进度等属性

我也写了一个简单的demo作为参考

实例化oss

javascript 复制代码
import OSS from 'ali-oss';
​
export const client = new OSS({
  accessKeyId: 'xxxxx', //访问键ID
  accessKeySecret: 'xxxxxx', //访问密钥
  bucket: 'a-bucket', //桶名
  secure: true, //是否启用HTTPS,https true   http false
  endpoint: 'oss-cn-beijing.aliyuncs.com' //地域节点 ==》外网访问
  // region : 'oss-cn-beijing'  // 就是外网访问的区域去掉.aliyuncs.com
})

upload

javascript 复制代码
upload(file, loading = true) {
    // 上传的文件名称
    const uuid = nanoid();
    const index = file.name.lastIndexOf(".")
    // 截取文件的后缀
    const suffix = file.name.substring(index + 1)
    // 二级目录名称
    const currentDate = tool.dateFormat(new Date(), 'yyyy-MM-dd')
    // 完整的上传路径   第一级路径/第二级路径/文件名   这个看不同的公司给定
    let fileName = "第一级路径/" + 第二级路径 + "/" + uuid + "." + suffix //定义唯一的文件名,打印出来的uid其实就是时间戳
   
    try{
        const data = await client.multipartUpload(fileName,file,{
            progress:function(percent){
                console.log("上传进度",percent)
            }
        })
    }catch(error){
        ElMessage.error("上传失败")
    }
  },
相关推荐
LY80934 分钟前
前端开发者的福音:用JavaScript实现Live2D虚拟人口型同步
前端·虚拟现实
林涧泣35 分钟前
【Uniapp-Vue3】uniapp创建组件
前端·javascript·uni-app
Sinyu101240 分钟前
Flutter 动画实战:绘制波浪动效详解
android·前端·flutter
pikachu冲冲冲44 分钟前
vue权限管理(动态路由)
前端·vue.js
一条不想当淡水鱼的咸鱼1 小时前
taro转H5端踩坑
前端·taro
傻小胖1 小时前
React Context用法总结
前端·react.js·前端框架
xsh801442422 小时前
Java Spring Boot监听事件和处理事件
java·前端·数据库
JINGWHALE12 小时前
设计模式 行为型 状态模式(State Pattern)与 常见技术框架应用 解析
前端·人工智能·后端·设计模式·性能优化·系统架构·状态模式
Smile_zxx2 小时前
windows 下npm 使用 n 切换node版本
前端·windows·npm
柠檬豆腐脑2 小时前
前端构建工具的发展和现状:Webpack、Vite和其他
前端·webpack·vite