likes
comments
collection
share

【NestJS实战】图片上传与下载上传 未使用数据库,暂且直接存 先装两个包 npm i multer -S 、npm

作者站长头像
站长
· 阅读数 33

上传

  1. 未使用数据库,暂且直接存
  2. 先装两个包 npm i multer -S npm i @types/multer -D
  3. 在 upload.module.ts 中引入
import { Module } from '@nestjs/common';
import { UploadService } from './upload.service';
import { UploadController } from './upload.controller';
import { MulterModule } from '@nestjs/platform-express';
import { diskStorage } from 'multer';
import { extname } from 'path'
const path = require('path')

@Module({
  controllers: [UploadController],
  providers: [UploadService],
  //! 注册 MulterModule
  imports: [MulterModule.register({
    //! 配置文件存储位置、文件重命名
    storage: diskStorage({
      destination: path.resolve(__dirname, '../images'),
      filename: (_, file, callback) => {
        // 文件名修改为时间戳,后缀名直接截取原文件的
        const rename = `${new Date().getTime()}${extname(file.originalname)}`
        return callback(null, rename)
      }
    })
  })]
})
export class UploadModule {}
  1. 在控制器 upload.controller.ts 中,接受 /upload/pic 的请求,使用 express 内置的文件拦截器 FileInterceptor ,去拦截指定字段的数据,例如我这里叫做 picFile。结合上装饰器UseInterceptor、UploadedFile
import { Controller, Post, UseInterceptors, UploadedFile } from '@nestjs/common';
import { UploadService } from './upload.service';
import { UpdateUploadDto } from './dto/update-upload.dto';
import { FileInterceptor } from '@nestjs/platform-express';

@Controller('upload')
export class UploadController {
  constructor(private readonly uploadService: UploadService) {}

  //! 接收 /upload/pic 的请求

  @Post('pic')

  //! 文件必须使用拦截器,拦截的字段为picFile
  @UseInterceptors(FileInterceptor('picFile'))

  // 参数装饰器 UploadedFile ,用于提取文件信息
  create(@UploadedFile() file) {
    return this.uploadService.create(file);
  }
}
  1. 在服务 upload.service.ts 中,使用参数对象file就能获取到图片保存的路径
import { Injectable } from '@nestjs/common';

@Injectable()
export class UploadService {
  create(file) {
    console.log('打印file', file)
    return {
      code: 200,
      result: '上传成功'
    };
  }
}

【NestJS实战】图片上传与下载上传 未使用数据库,暂且直接存 先装两个包 npm i multer -S 、npm

  1. 提供一个静态资源的路径,让前端可以直接访问上传的文件。在 main.ts 中,用 useStaticAssets() 配置静态资源目录,第二个参数是虚拟路径,可选

【NestJS实战】图片上传与下载上传 未使用数据库,暂且直接存 先装两个包 npm i multer -S 、npm

没有虚拟路径:

【NestJS实战】图片上传与下载上传 未使用数据库,暂且直接存 先装两个包 npm i multer -S 、npm

有虚拟路径:

【NestJS实战】图片上传与下载上传 未使用数据库,暂且直接存 先装两个包 npm i multer -S 、npm

图片下载

方式1:直接使用url下载

后端

在控制器 download.controller.ts 中,接收 /download/byUrl 的请求。在服务 download.service.ts 中,直接获取文件路径,并用响应对象的 .download() 方法发出去

【NestJS实战】图片上传与下载上传 未使用数据库,暂且直接存 先装两个包 npm i multer -S 、npm

前端

直接打开一个窗口即可下载

<template>
  <button @click="handleDownByUrl">使用url下载</button>
</template>

<script setup>
const handleDownByUrl = () => {
  window.open('http://localhost:3000/download/byURL')
}
</script>

方式2:使用二进制流

后端

  1. 在控制器 download.controller.ts 中,接收 /download/byBinary 的请求。
  2. 在服务 download.service.ts 中
  • new一个 zip.Stream 对象,它将图片压缩成二进制格式的.zip包
  • 获取图片的路径,使用zip.Stream 对象将其转换为二进制
  • 最后调用zip.Stream 对象的 .pipe() 将文件返回出去

【NestJS实战】图片上传与下载上传 未使用数据库,暂且直接存 先装两个包 npm i multer -S 、npm

前端

  1. 将响应的二进制数据转换为 Blob 格式

  2. 使用 URL.createObjectURL() 将其转为url字符串

  3. url字符串塞入a标签的href属性

  4. 手动触发a标签的点击事件

<template>
  <button @click="handleDownByBinary">使用二进制下载</button>
</template>

<script setup>
const handleDownByBinary = async () => {
  // 1. 发请求获取二进制文件
  const response = await fetch('http://localhost:3000/download/byBinary')

  // 2. 调用响应对象的 arrayBuffer 方法,将后端的返回值读取为ArrayBuffer
  const arrayBuffer = await response.arrayBuffer()

  // 3. 转为Blob
  const blob = new Blob([arrayBuffer])

  // 4. 再转换为一条url
  const urlStr = URL.createObjectURL(blob)

  // 5. urlStr塞入a标签的href属性中
  const a = document.createElement('a')
  a.href = urlStr
  a.download = 'zhouziyan.zip'

  document.body.appendChild(a) // 插入页面

  // 6. 手动触发点击事件
  a.click()

  document.body.removeChild(a); // 下载后清理  

  URL.revokeObjectURL(urlStr); // 释放URL对象 
}
</script>
转载自:https://juejin.cn/post/7400609489789829159
评论
请登录