最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Nest.js使用multer實現(xiàn)文件上傳功能

 更新時間:2024年03月15日 08:18:44   作者:云牧  
這篇文章主要為大家詳細介紹了Nest.js鵝湖使用multer實現(xiàn)文件上傳功能,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

項目創(chuàng)建與配置

新建 nest 項目:

nest new nest-multer-upload -p npm

安裝下 multer 的 ts 類型的包:

npm install @types/multer -D

讓 nest 服務(wù)支持跨域:

單文件上傳

添加一個 handler:

@Post('aaa')
@UseInterceptors(
  FileInterceptor('aaa', {
    dest: 'uploads',
  }),
)
uploadFile(@UploadedFile() file: Express.Multer.File, @Body() body) {
  console.log('body', body);
  console.log('file', file);
}

這里使用 FileInterceptor 提取請求中的 aaa 字段,并通過 UploadedFile 裝飾器將其作為參數(shù)傳遞。

當我們運行 nest start --watch 的時候,uploads 文件夾就會創(chuàng)建。

前端代碼:

<!DOCTYPE html>
<html lang="en">
	<head>
		<script src="https://unpkg.com/axios@0.24.0/dist/axios.min.js"></script>
	</head>
	<body>
		<input id="fileInput" type="file" multiple />
		<script>
			const fileInput = document.querySelector('#fileInput')

			async function formData() {
				const data = new FormData()
				data.set('name', 'Yun')
				data.set('age', 20)
				data.set('aaa', fileInput.files[0])

				const res = await axios.post('http://localhost:3000/aaa', data)
				console.log(res)
			}

			fileInput.onchange = formData
		</script>
	</body>
</html>

服務(wù)端就打印了 file 對象和 body 字段,并且文件也保存到了 uploads 目錄:

多文件上傳

@Post('bbb')
@UseInterceptors(
  FilesInterceptor('bbb', 3, {
    dest: 'uploads',
  }),
)
uploadFiles(
  @UploadedFiles() files: Array<Express.Multer.File>,
  @Body() body,
) {
  console.log('body', body);
  console.log('files', files);
}

把 FileInterceptor 換成 FilesInterceptor,把 UploadedFile 換成 UploadedFiles,都是多加一個 s。

前端代碼:

async function formData2() {
  const data = new FormData()
  data.set('name', 'Yun')
  data.set('age', 20)
  ;[...fileInput.files].forEach(item => {
    data.append('bbb', item)
  })

  const res = await axios.post('http://localhost:3000/bbb', data, {
    headers: { 'content-type': 'multipart/form-data' },
  })
  console.log(res)
}

這樣就可以上傳多文件了:

如果有多個文件的字段,和 multer 里類似,使用這種方式來指定:

@Post('ccc')
@UseInterceptors(FileFieldsInterceptor([
    { name: 'aaa', maxCount: 2 },
    { name: 'bbb', maxCount: 3 },
], {
    dest: 'uploads'
}))
uploadFileFields(@UploadedFiles() files: { aaa?: Express.Multer.File[], bbb?: Express.Multer.File[] }, @Body() body) {
    console.log('body', body);
    console.log('files', files);
}

前端代碼:

async function formData3() {
  const data = new FormData()
  data.set('name', 'Yun')
  data.set('age', 20)
  data.append('aaa', fileInput.files[0])
  data.append('aaa', fileInput.files[1])
  data.append('bbb', fileInput.files[2])
  data.append('bbb', fileInput.files[3])

  const res = await axios.post('http://localhost:3000/ccc', data)
  console.log(res)
}

后端收到了上傳的 aaa、bbb 的文件:

如果不知道前端上傳字段,哪些是用于文件上傳的字段,可以使用 AnyFilesInterceptor:

@Post('ddd')
@UseInterceptors(AnyFilesInterceptor({
    dest: 'uploads'
}))
uploadAnyFiles(@UploadedFiles() files: Array<Express.Multer.File>, @Body() body) {
    console.log('body', body);
    console.log('files', files);
}

前端代碼:

async function formData4() {
  const data = new FormData()
  data.set('name', 'Yun')
  data.set('age', 20)
  data.set('aaa', fileInput.files[0])
  data.set('bbb', fileInput.files[1])
  data.set('ccc', fileInput.files[2])
  data.set('ddd', fileInput.files[3])

  const res = await axios.post('http://localhost:3000/ddd', data)
  console.log(res)
}

同樣識別出了所有 file 字段:

這就是 Nest 上傳文件的方式。

自定義存儲

import * as multer from 'multer';
import * as fs from 'fs';
import * as path from 'path';

const storage = multer.diskStorage({
  // 自定義目錄
  destination: function (req, file, cb) {
    try {
      fs.mkdirSync(path.join(process.cwd(), 'my-uploads'));
    } catch (e) {}

    cb(null, path.join(process.cwd(), 'my-uploads'));
  },
  // 自定義文件
  filename: function (req, file, cb) {
    const uniqueSuffix =
      Date.now() +
      '-' +
      Math.round(Math.random() * 1e9) +
      '-' +
      file.originalname;
    cb(null, file.fieldname + '-' + uniqueSuffix);
  },
});

export { storage };

然后在 controller 使用這個 storage:

其實 Nest 上傳文件的方式就是對 multer 做了一層簡單的封裝。

文件校驗

此外我們還可能對上傳文件的大小,類型做限制。這部分可以放在 pipe 做。

我們生成一個 pipe:

nest g pipe file-size-validation-pipe --no-spec --flat

添加檢查文件大小的邏輯,大于 10k 就拋出異常,返回 400 的響應(yīng):

import {
  PipeTransform,
  Injectable,
  ArgumentMetadata,
  HttpException,
  HttpStatus,
} from '@nestjs/common';

@Injectable()
export class FileSizeValidationPipe implements PipeTransform {
  transform(value: Express.Multer.File, metadata: ArgumentMetadata) {
    if (value.size > 10 * 1024) {
      throw new HttpException('文件大于 10k', HttpStatus.BAD_REQUEST);
    }
    return value;
  }
}

加到 UploadedFile 的參數(shù)里:

當上傳一個圖片大于 10k 的時候:

但像文件大小、類型的校驗這種常見的邏輯,Nest 內(nèi)置了:

@Post('fff')
@UseInterceptors(FileInterceptor('aaa', {
    dest: 'uploads'
}))
uploadFile3(@UploadedFile(new ParseFilePipe({
    validators: [
      new MaxFileSizeValidator({ maxSize: 1000 }),
      new FileTypeValidator({ fileType: 'image/jpeg' }),
    ],
})) file: Express.Multer.File, @Body() body) {
    console.log('body', body);
    console.log('file', file);
}

MaxFileSizeValidator 是校驗文件大小、FileTypeValidator 是校驗文件類型。

返回的也是 400 響應(yīng),并且 message 說明了具體的錯誤信息。

而且這個錯誤信息 message 可以通過 exceptionFactory 工廠函數(shù)自定義。

我們也可以自己實現(xiàn)這樣的 validator,只要繼承 FileValidator 就可以:

import { FileValidator } from '@nestjs/common';

export class MyFileValidator extends FileValidator {
  constructor(options) {
    super(options);
  }

  isValid(file: Express.Multer.File): boolean | Promise<boolean> {
    if (file.size > 10000) {
      return false;
    }
    return true;
  }
  buildErrorMessage(file: Express.Multer.File): string {
    return `文件 ${file.originalname} 大小超出 10k`;
  }
}

然后在 controller 用一下:

瀏覽器上傳文件:

可以看到我們自定義的 FileValidator 生效了。

最后注意限制文件大小,大小超過之后文件最終還是會上傳到服務(wù)器,因為文件寫入才能拿到相關(guān)信息,我們可以根據(jù)路徑來刪除不合規(guī)的文件。

以上就是Nest.js使用multer實現(xiàn)文件上傳功能的詳細內(nèi)容,更多關(guān)于Nest.js multer文件上傳的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Node.js使用Express框架遇到中文亂碼問題的解決方案

    Node.js使用Express框架遇到中文亂碼問題的解決方案

    在Node.js中使用Express框架時,處理中文亂碼問題通常涉及到設(shè)置正確的字符編碼和中間件,以下是一些常見的解決方案,需要的朋友可以參考下
    2025-11-11
  • Nodejs 模塊化實現(xiàn)示例深入探究

    Nodejs 模塊化實現(xiàn)示例深入探究

    這篇文章主要為大家介紹了Nodejs 模塊化實現(xiàn)示例深入探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-11-11
  • Node.js?中的?RSA?加密、解密、簽名與驗證

    Node.js?中的?RSA?加密、解密、簽名與驗證

    RSA加密算法因其非對稱的特性,廣泛應(yīng)用于數(shù)據(jù)的加密、解密、簽名和驗證等安全領(lǐng)域,本文主要介紹了Node.js?中的?RSA?加密、解密、簽名與驗證,具有一定的參考價值,感興趣的可以了解一下
    2024-08-08
  • Node.js實現(xiàn)批量去除BOM文件頭

    Node.js實現(xiàn)批量去除BOM文件頭

    這篇文章主要介紹了Node.js實現(xiàn)批量去除BOM文件頭,本文直接給出實現(xiàn)代碼,需要的朋友可以參考下
    2014-12-12
  • nodejs下載指定版本完整圖文步驟

    nodejs下載指定版本完整圖文步驟

    node.js官方版是一款專業(yè)性非常強的瀏覽輔助工具軟件,這款軟件操作十分的簡單、功能也是非常的強勁,下面這篇文章主要給大家介紹了關(guān)于nodejs下載指定版本的相關(guān)資料,需要的朋友可以參考下
    2023-12-12
  • nodejs個人博客開發(fā)第二步 入口文件

    nodejs個人博客開發(fā)第二步 入口文件

    這篇文章主要為大家詳細介紹了nodejs個人博客開發(fā)的入口文件,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • express的中間件cookieParser詳解

    express的中間件cookieParser詳解

    這篇文章主要介紹了node.js中express的中間件cookieParser的使用方法,需要的朋友可以參考下
    2014-12-12
  • puppeteer實現(xiàn)html截圖的示例代碼

    puppeteer實現(xiàn)html截圖的示例代碼

    通過Puppeteer的提供的api直接控制Chrome模擬大部分用戶操作來進行UI Test或者作為爬蟲訪問頁面來收集數(shù)據(jù),這篇文章主要介紹了puppeteer實現(xiàn)截圖的示例代碼,感興趣的可以了解一下
    2019-01-01
  • 學(xué)習(xí)Node.js模塊機制

    學(xué)習(xí)Node.js模塊機制

    這篇文章主要為大家詳細介紹了Node.js模塊機制,一篇關(guān)于Node.js模塊機制的學(xué)習(xí)筆記,感興趣的小伙伴們可以參考一下
    2016-10-10
  • npm?install?-g?@vue/cli常見問題解決匯總

    npm?install?-g?@vue/cli常見問題解決匯總

    這篇文章主要給大家介紹了關(guān)于npm?install?-g?@vue/cli常見問題解決的相關(guān)資料,文中通過實例代碼將解決的方式介紹的非常詳細,對遇到這個問題的朋友具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2022-08-08

最新評論

镇雄县| 通山县| 黑水县| 大足县| 财经| 海原县| 新闻| 临潭县| 临潭县| 湄潭县| 固始县| 湖南省| 高州市| 鄂托克前旗| 松潘县| 南京市| 黄山市| 宁化县| 什邡市| 河北区| 台州市| 凤庆县| 新乐市| 新津县| 天气| 藁城市| 汉沽区| 新昌县| 攀枝花市| 瓦房店市| 乌鲁木齐县| 怀集县| 武威市| 闽侯县| 北辰区| 长宁县| 怀远县| 通河县| 瑞金市| 油尖旺区| 普安县|