美文网首页
node框架文件上传到阿里云OSS

node框架文件上传到阿里云OSS

作者: BA_凌晨四点 | 来源:发表于2022-09-29 11:30 被阅读0次

    本文说明 node中两大框架:nest.js 和 egg.js
    需要依赖 ali-oss 这个阿里云提供的库

    环境1:Nest.js

    方法一:

    先上传到服务器,再从服务器中转到 阿里云

    // controller.ts
    
      @Post('oss')
      @UseInterceptors(
        FileInterceptor('file', {
          storage: multer.diskStorage({
            destination: (req, file, cb) => {
              // 开启服务器本地存储路径
              cb(null, 'D:/barry/temp');
            },
            filename: (req, file, cb) => {
              cb(null, file.originalname);
            },
          }),
        }),
      )
      // 接着上传到oss
      async uploadImage(@UploadedFile() file: any): Promise<any> {
        return await this.uploadService.uploadImage(file);
      }
    
    // upload.service.ts
    
    async uploadImage(file: any): Promise<any> {
        try {
          const ossService = new OssService();
          const ossUrl = await ossService.putOssFile(
            `/slideShow/${file.originalname}`,  // 存放的 ali-oss 位置
            `D:/barry/temp/${file.originalname}`,  // 存放的本地(服务器的位置)
          );
          return {
            code: 200,
            data: ossUrl,
            message: '上传成功',
          };
        } catch (error) {
          return {
            code: 503,
            msg: `Service error: ${error}`,
          };
        }
      }
    

    利用 ali-oss 提供的 put 方法

    // oss.service.ts
    
     public constructor() {
        this.client = new OSS({
          accessKeyId: ossConfig.accessKeyId,
          accessKeySecret: ossConfig.accessKeySecret,
          region: ossConfig.region,
          bucket: ossConfig.bucket,
        });
      }
    
      // 上传文件到oss 并返回  图片oss 地址
      public async putOssFile(ossPath: string, localPath: string): Promise<string> {
        let res: any;
        try {
          res = await this.client.put(ossPath, localPath);
          // 将文件设置为公共可读
          await this.client.putACL(ossPath, 'public-read');
        } catch (error) {
          console.log(error);
        }
        return res.url;
      }
    

    这个方法有个问题就是:必须要依赖服务器做中转,也就是服务器存一份,阿里云存一份。

    方法二:

    直接上传到阿里云

    // upload.controller.ts
    
      @Post('oss')
      @UseInterceptors(FileInterceptor('file', {}))
      async uploadImage(@UploadedFile() file: any): Promise<any> {
        await this.uploadService.uploadImage(file);
      }
    }
    
    // upload.service.ts
    
    async uploadImage(file: any): Promise<any> {
        try {
          const ossService = new OssService();
          const ossUrl = await ossService.putOssFile(file);
          return {
            code: 200,
            data: ossUrl,
            message: '上传成功',
          };
        } catch (error) {
          return {
            code: 503,
            msg: `Service error: ${error}`,
          };
        }
      }
    

    利用 ali-oss 的 putStream 方法

    import { Readable } from 'stream';
    
    public async putOssFile(file): Promise<string> {
    /**
     * 将buffer转为Stream流
     * @param binary file.buffer
     * @returns 
     */
    function bufferToStream(binary) {
        const readableInstanceStream = new Readable({
          read() {
            this.push(binary);
            this.push(null);
          },
        });
      return readableInstanceStream;
     }
    
    const res = await this.client.putStream('others/b.png', bufferToStream(file.buffer), {
          contentLength: file.size,
    });
    
    return res.url;
    }
    

    环境2:Egg.js

    直接上传到阿里云

    egg自带有multipart,不再需要额外转换Stream流,听说是封装的co-busboy

    // upload.js
    // 阿里云oss
    const client = new oss({
       accessKeyId: ossConfig.accessKeyId,
       accessKeySecret: ossConfig.accessKeySecret,
       region: ossConfig.region,
       bucket: ossConfig.bucket,
    });
    
      /**
       * 上传处理
       */
      async doAdd() {
        const { ctx, service, app } = this;
        // 利用 egg 提供的 multipart 将文件转为流式Stream类型
        let parts = ctx.multipart({ autoFields: true });
        let stream;
    
        client
          .listBuckets({
            'max-keys': 10,
          })
          .then((result) => {
            console.log(result);
          });
    
        while ((stream = await parts()) != null) {
          if (!stream.filename) {
            break;
          }
          // 修改名字 以及对应的阿里云路径
          let name = `test${path.extname(stream.filename)}`;
          client
            .putStream(name, stream)
            .then(function (r1) {
              console.log('put success: %j', r1);
              return client.get('object');
            })
            .then(function (r2) {
              console.log('get success: %j');
            })
            .catch(function (err) {
              console.error('error: %j');
            });
        }
        ctx.body = 'ok';
      }
    

    删除阿里云的文件

    只需要调用 ali-oss 提供的 delete 方法即可

      /**
       * 删除oss文件
       */
      public async deleteOssFile() {
        const resp = await this.client.delete('slideShow/b.png');  // 阿里云文件路径
        console.log('删除成功??', resp);
      }
    

    相关文章

      网友评论

          本文标题:node框架文件上传到阿里云OSS

          本文链接:https://www.haomeiwen.com/subject/msycartx.html