欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

在?node?中使用?koa-multer?庫(kù)上傳文件的方式詳解

 更新時(shí)間:2024年01月15日 11:14:34   作者:劫辭  
本文主要介紹了上傳單個(gè)文件、多個(gè)文件,文件數(shù)量大小限制、限制文件上傳類型和對(duì)上傳的圖片進(jìn)行不同大小的裁剪,對(duì)node使用?koa-multer?庫(kù)上傳文件相關(guān)知識(shí)感興趣的朋友一起看看吧

本文主要介紹了上傳單個(gè)文件、多個(gè)文件,文件數(shù)量大小限制、限制文件上傳類型和對(duì)上傳的圖片進(jìn)行不同大小的裁剪,閱讀本篇文章需要具備一定的 node 和 koa 框架的基礎(chǔ)知識(shí)以及 async await 語(yǔ)法,如果遇到不了解的知識(shí)點(diǎn)可以自己查閱資料,不了解按照本文的案例也可以實(shí)現(xiàn),希望可以通過(guò)本篇文章讓你掌握在 node 中實(shí)現(xiàn)文件上傳,如果只需要源碼,可在文章最后進(jìn)行獲取

環(huán)境準(zhǔn)備

  • 需要本機(jī)具備 nodejs 環(huán)境
  • postman 接口測(cè)試工具,或者其他測(cè)試工具都可以
  • 需要的依賴如下:
{
   "jimp": "^0.22.5",
   "koa": "^2.14.1",
   "koa-multer": "^1.0.2",
   "koa-router": "^12.0.0",
   "nodemon": "^2.0.20"
}
  • nodemon:讓項(xiàng)目啟動(dòng)后,代碼更改自動(dòng)重新啟動(dòng)服務(wù),方便調(diào)試

當(dāng)然如果你希望輸入 nodemon 命令就可以啟動(dòng)項(xiàng)目可以在 package.json 文件中進(jìn)行如下設(shè)置:

{
  "name": "node-upload",
  "version": "1.0.0",
  "description": "file upload",
  "main": "./main.js", // 設(shè)置為你項(xiàng)目的入口文件路徑
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "nodemon" // 設(shè)置啟動(dòng)命令為 nodemon 
  },
  "author": "coderjc",
  "license": "ISC",
  "dependencies": {
    "jimp": "^0.22.5",
    "koa": "^2.14.1",
    "koa-multer": "^1.0.2",
    "koa-router": "^12.0.0",
    "nodemon": "^2.0.20"
  }
}
  • koa:是一個(gè)新的 web 框架,想在 node 中使用需要這個(gè)依賴
  • koa-route:koa 框架的路由系統(tǒng)采用第三方庫(kù)的形式實(shí)現(xiàn)
  • koa-multer:幫助我們?cè)?koa 中進(jìn)行文件上傳
  • jimp:將圖片進(jìn)行不同大小的裁剪

項(xiàng)目初始化

  • 本文主為了案例演示,所以不進(jìn)行對(duì)項(xiàng)目進(jìn)行模塊化的劃分,統(tǒng)一在入口文件中進(jìn)行演示,初始化入口文件如下:
// 引入內(nèi)置模塊
const path = require('path')
// 引入第三方庫(kù)
const Koa = require('koa')
const Router = require('koa-router')
const multer = require('koa-multer')
const Jimp = require('jimp')
// 創(chuàng)建app實(shí)例
const app = new Koa()
// 創(chuàng)建路由實(shí)例
//	- prefix:配置根路徑
const uploadRouter = new Router({ prefix: '/upload' })
// 注冊(cè)接口
app.use(uploadRouter.routes())
// 監(jiān)聽(tīng)
app.listen(8001, () => {
	console.log('koa server start success~')
})

創(chuàng)建上傳單個(gè)文件接口

我們通過(guò)創(chuàng)建的路由實(shí)例,可以在上面指定 http 請(qǐng)求類型,上傳文件為 post 請(qǐng)求,因?yàn)橐呀?jīng)配置了根路徑,所以上傳單個(gè)文件的路徑為 / ,表示為默認(rèn)路徑,具體路由系統(tǒng)這部分本文不在進(jìn)行贅述,創(chuàng)建接口如下:

// 單文件上傳接口
uploadRouter.post('/', (ctx, next) => {
	ctx.body = '文件上傳成功' // ctx.body 方法可以返回指定返回給客戶端的信息
})

上述就是在 koa 中一個(gè)接口的創(chuàng)建,我們可以使用 postman 測(cè)試一下工具是否搭建成功,postman 的使用方式本文不進(jìn)行講解,使用很簡(jiǎn)單,大家查閱資料即可,結(jié)果如下:

返回 文件上傳成功 或自定義的信息,即表示接口搭建成功

使用 koa-multer 實(shí)現(xiàn)單文件上傳

  • 在實(shí)現(xiàn)文件上傳之前,我們需要一個(gè)文件夾來(lái)存儲(chǔ)我們上傳的文件,在真實(shí)的開(kāi)發(fā)中,一般會(huì)有一臺(tái)其余的服務(wù)器用來(lái)存儲(chǔ)文件,本案例就直接用本地代替了,我們?cè)陧?xiàng)目的根目錄中創(chuàng)建文件夾 uploads
  • 在實(shí)現(xiàn)之前,我們先來(lái)看一寫參數(shù)解析,摘自官網(wǎng),大家可以放心參考
屬性名描述
fieldname表單中指定的字段名稱
originalname用戶計(jì)算機(jī)上文件的名稱
encoding文件的編碼類型
mimetype文件的 MIME 類型
size文件大?。ㄒ?bytes 為單位)
destination保存文件的文件夾
filename控件中的文件名
path上傳文件的完整路徑
bufferBuffer 整個(gè)文件

不帶文件后綴名存儲(chǔ)

在 koa-multer 中實(shí)現(xiàn)文件上傳具備兩種寫法:

  • 不帶文件后綴名存儲(chǔ)
  • 后端代碼:
// 配置 multer
const upload = multer({
	dest: './uploads' // 文件存儲(chǔ)地址
})
// 使用 single() 方法獲取單張圖片,此方法需要傳遞一個(gè)參數(shù),為前端是上傳鍵名一致
// 	- single 方法會(huì)返回一個(gè)函數(shù),可以作為一個(gè)中間件使用,根據(jù)這個(gè)特性,我們可以使用使用一個(gè)變量接收返回的函數(shù)
const one = upload.single('file')
// 將返回的函數(shù) one 作為中間件
uploadRouter.post('/', one, (ctx, next) => {
    // 如果你需要在后面的中間件獲取文件信息,可以使用 ctx.req.file獲取
	ctx.body = {
		flie: ctx.req.file
	} 
})

postman 模擬前端發(fā)送請(qǐng)求

我們來(lái)看一下上傳前的 uploads 文件夾,展開(kāi)沒(méi)有任何內(nèi)容

上傳后 uploads 文件夾內(nèi)容如下:不過(guò)由于沒(méi)有添加后綴名,無(wú)法直接查看,可以自己添加后綴名進(jìn)行查看

5. 來(lái)看一下返回給客戶端的文件信息具體內(nèi)容:

文件攜帶后綴名存儲(chǔ)

  • 如果需要設(shè)置后綴名,我們有兩個(gè)選項(xiàng)可用,destinationfilename。它們都是確定文件存儲(chǔ)位置的函數(shù)
  • destination:用于確定存儲(chǔ)文件的地址
  • filename:用于確定文件夾中的文件命名
  • 首先我們需要使用配置一下兩個(gè)函數(shù),如下:
// 文件配置
//  - req 請(qǐng)求信息
//  - flie 文件信息
//  - cb 回調(diào)函數(shù)
const storage = multer.diskStorage({
	// 存儲(chǔ)路徑
	destination: (req, flie, cb) => {
		// cb: (error: Error | null, destination: string)
		//  - 通過(guò)將鼠標(biāo)放入 cb 上,會(huì)出現(xiàn)一個(gè)提示,傳入兩個(gè)參數(shù)
		//    - 參數(shù)一:傳入一個(gè)錯(cuò)誤
		//    - 參數(shù)二:傳入存儲(chǔ)路徑
		cb(null, './uploads')
	},
	// 設(shè)置文件名
	filename: (req, flie, cb) => {
		// path.extname() 方法獲取文件后綴名
		//  - originalname	用戶計(jì)算機(jī)上的文件的名稱
         // 為了保證名稱的唯一性,可以使用時(shí)間戳作為文件名稱
         // path.extname() 可以獲取一個(gè)文件的后綴名
		cb(null, Date.now() + path.extname(flie.originalname))
	}
})
// multer 方法會(huì)返回一個(gè)函數(shù),作為中間件
//  - 將配置項(xiàng)傳入 multer
const upload = multer({ storage })
const one = upload.single('file')
// 將返回的函數(shù) one 作為中間件
uploadRouter.post('/', one, (ctx, next) => {
    // 如果你需要在后面的中間件獲取文件信息,可以使用 ctx.req.file獲取
	ctx.body = {
		flie: ctx.req.file
	} 
})

演示效果我這里就不在進(jìn)行展示了,大家可以自行嘗試

采用那種方式都應(yīng)該是實(shí)際需求為準(zhǔn),沒(méi)有定論,大家自行斟酌即可

使用 koa-multer 實(shí)現(xiàn)多文件上傳

實(shí)現(xiàn)多文件上傳官方文檔中給我們提供了兩個(gè)方法,array 和 fields,具體使用方法與區(qū)別看后續(xù)講解

array 的使用

array 方法的使用與單個(gè)文件上傳的區(qū)別很小,首先我我們需要將調(diào)用的方法從 single 改成 array,如下:

//   - 第一個(gè)參數(shù)指定文件名稱
//   - 第二個(gè)參數(shù)指定文件上傳的數(shù)量
// 其余文件配置項(xiàng)即使用與單文件上傳別無(wú)而至
// - 接收函數(shù)變量為了符合語(yǔ)義我這里改為
const more = upload.array('files', 2)

為了方便給大家演示,多文件上傳我更換了一個(gè)接口路徑,如下:

uploadRouter.post('/more', more, pictureResize, (ctx, next) => {
    // 如果是非文件的文本信息,可以從 ctx.req.body 獲取,這里會(huì)給大家進(jìn)行一個(gè)展示
    // 單文件獲取信息方式是 ctx.req.file,而多文件是 ctx.req.files,需要大家注意一下
	ctx.body = {
		text: ctx.req.body || '',
		flies: ctx.req.files
	}
})

配置完成后我們使用 postman 模擬請(qǐng)求發(fā)送,如下:

我們先來(lái)看一下上傳的文件,是否在 uploads 文件夾中成功上傳,為了方便對(duì)比,我已經(jīng)提前將 uploads 文件夾清空,查看一下結(jié)果,如下:

在看一下返回給客戶端的信息

當(dāng)然超過(guò)文件限制數(shù)量,會(huì)導(dǎo)致報(bào)錯(cuò),讓程序崩潰,具體的如何處理這個(gè)異常,我們后續(xù)會(huì)講解到

fields 的使用

fields 的使用方法與 array 大同小異,只是在使用方式上有一些差距,我們先看一下具體上使用的差距,如下:

// 對(duì)fields多文件上傳時(shí)出現(xiàn)的錯(cuò)誤進(jìn)行捕獲
// fields應(yīng)該是一個(gè)對(duì)象數(shù)組,并且 name 可以選擇一個(gè) maxCount,
//  - name 即文件的字段名
//  - maxCount 即指定這個(gè)子段的文件可以上傳的數(shù)量
const moreFields = upload.fields([
	{ name: 'avatar', maxCount: 1 },
	{ name: 'files', maxCount: 2 }
])

還是為了進(jìn)行演示,我新建了一個(gè)接口路徑,如下:

// 請(qǐng)求路徑修改為
uploadRouter.post('/fields', moreFields, (ctx, next) => {
	ctx.body = {
		text: ctx.req.body || '',
		flies: ctx.req.files
	}
})

使用 postman 發(fā)送請(qǐng)求,如下:

還是清空了 uploads 文件夾,方便我們查看,如下:

array 與 fields 的區(qū)別

相信經(jīng)過(guò)上面兩個(gè)案例的對(duì)比,大家對(duì)兩者的區(qū)別已經(jīng)知道了,兩者的區(qū)別在于:array 方法接收的多個(gè)文件必須是同一字段名稱,fields 是可以對(duì)多個(gè)字段名稱進(jìn)行獲取的,一般情況下推薦大家使用 arrary 方法,別問(wèn),問(wèn)就是方便好用

對(duì)文件進(jìn)行限制-limits

什么是對(duì)文件的限制,比如限制一下當(dāng)前文件的上傳的大小,數(shù)量等等,還是一樣我給大家從官方上帶來(lái)了 limits 的屬性解析,如下:

鑰匙描述默認(rèn)
fieldNameSize最大字段名稱大小100 字節(jié)
fieldSize最大字段值大?。ㄒ宰止?jié)為單位)1MB
fields非文件字段的最大數(shù)量無(wú)窮
fileSize對(duì)于多部分表單,最大文件大?。ㄒ宰止?jié)為單位)無(wú)窮
files對(duì)于多部分表單,文件字段的最大數(shù)量無(wú)窮
parts對(duì)于多部分表單,部分的最大數(shù)量(字段 + 文件)無(wú)窮
headerPairs對(duì)于多部分表單,要解析的標(biāo)題鍵=>值對(duì)的最大數(shù)量2000

我給大家解析一下非文件字段,一般表單提交的時(shí)候,我們只有 文本和文件 的區(qū)別,非文件指的就是文本數(shù)據(jù),這里的文本數(shù)據(jù)可不是 txt 文件結(jié)尾的,就如上述提交中我們提交的文本數(shù)據(jù),即下圖中橙色框中部分,如下:

那我現(xiàn)在介紹一下 limits 的使用,如下:

// 限制上傳的文件
// tips:使用的如果是 single 方法則只能發(fā)送 1 個(gè)文件,否則會(huì)報(bào)錯(cuò):Unexpected field,所以單個(gè)文件時(shí)不用添加 files 限制單次文件數(shù)量
// 這里附上單位轉(zhuǎn)換
// B(Byte) 1Byte=8bit
// KB 1KB=1024B
// MB 1MB=1024KB
// GB 1GB=1024MB
// TB 1TB=1024GB
const limits = {
	fields: 10,
	fileSize: 104857600,
	files: 5
}
// 將此項(xiàng)傳入 multer
const upload = multer({ storage, limits })

至于效果演示我這里就不進(jìn)行演示了,屬性比較多,大家有興趣可以自行演練

過(guò)濾文件-fileFilter

文件過(guò)濾指的是排除一些指定類型的文件,為了安全考慮,我們通常會(huì)將可執(zhí)行文件排除,不過(guò)這里只是作于演示,我就采用排除 png 格式的文件

fileFiter 為我們提供了三個(gè)回調(diào)函數(shù),分別是:

  • cb(null, true):放行文件
  • cb(null, false):禁止文件
  • cb(new Error(‘png格式文件不允許上傳~’)):拋出一個(gè)錯(cuò)誤

fileFiter 的使用如下:

const fileFilter = (req, file, cb) => {
    // 獲取文件類型后綴名
	const type = path.extname(file.originalname)
    // 排除 png 格式的圖片
	if (type !== '.png') {
		cb(null, true)
	} else {
		cb(null, false)
	}
}
// 將此項(xiàng)傳入 multer
const upload = multer({fileFilter, storage, limits })

按照上述的例子就可以對(duì)文件類型進(jìn)行過(guò)濾了,我們先來(lái)看在 postman 中發(fā)送請(qǐng)求,如下:

我們看一下 uploads 文件下的內(nèi)容,如下:

可以看到 png 的格式是沒(méi)有上傳的,我們?cè)倏匆幌路祷亟o客戶端的結(jié)果,如下:

是不是發(fā)現(xiàn)好像這樣有一些不友好,并不清楚那個(gè)文件沒(méi)有符合格式,沒(méi)有上傳成功,怎么實(shí)現(xiàn)這個(gè)功能暫且先放下,稍后在講,我們先看一下第三個(gè)回調(diào)函數(shù),修改一下 fileFilter 的配置項(xiàng),如下:

const fileFilter = (req, file, cb) => {
    // 獲取文件類型后綴名
	const type = path.extname(file.originalname)
    // 排除 png 格式的圖片
	if (type !== '.png') {
		cb(null, true)
	} else {
        // 在此處拋出一個(gè)錯(cuò)誤
		cb(new Error('png格式文件不允許上傳~'))
	}
}

postmon 模擬的請(qǐng)求不變,我們?cè)诳匆幌聢?zhí)行結(jié)果,看看 uploads 文件夾下是否多出文件,如下:

可以看到圖片依然沒(méi)有增加,證明此次因?yàn)橐粋€(gè)文件的不符合,導(dǎo)致其他符合的文件也沒(méi)有上傳,這樣一看好像也是不太符合我們的需求,在解決之前我們看一下返回給客戶端的結(jié)果,如下:

這樣雖然有了提示,但是就沒(méi)有實(shí)現(xiàn)符合的文件成功存儲(chǔ)的功能,關(guān)于這一點(diǎn)我在官網(wǎng)中也沒(méi)有找到合適的例子,所以我采用了一個(gè)掛載變量的方法來(lái)實(shí)現(xiàn)這個(gè)效果,如下:

const path = require('path')
const Koa = require('koa')
const Router = require('koa-router')
const multer = require('koa-multer')
const Jimp = require('jimp')
const app = new Koa()
// 在頂部注冊(cè)一個(gè)普通的中間件
//  - 在這里注冊(cè)中間件會(huì)讓任何請(qǐng)求都會(huì)觸發(fā)這個(gè)中間件,原因的話我這里就不贅述了大家可以去學(xué)習(xí)一個(gè)相關(guān)的知識(shí)
//  - 當(dāng)然可以只注冊(cè)在需要處理文件上傳的接口處,具體位置自己決定即可
app.use(async (ctx, next)=>{
    // 通過(guò)給 ctx.req 屬性上掛在一個(gè) 錯(cuò)誤文件的 屬性,賦值為空數(shù)組,來(lái)記錄本次上傳失敗的文件名稱
    ctx.req.failFiles = []
    await next()
})
// storage limits 等配置項(xiàng)我這里就不在書寫了,大家自行補(bǔ)充即可,fileFilter 配置項(xiàng)需要更改
const fileFilter = (req, file, cb) => {
	const type = path.extname(file.originalname)
	if (type !== '.png') {
		cb(null, true)
	} else {
         // 如果文件類型不符合就會(huì)經(jīng)過(guò)這里,所以可以在這里將失敗的文件名稱存儲(chǔ)進(jìn) failFiles 數(shù)組
		req.failFiles.push(file.originalname)
		cb(null, false)
	}
}
const upload = multer({fileFilter, storage, limits })
const uploadRouter = new Router({ prefix: '/upload' })
uploadRouter.post('/more', captures, (ctx, next) => {
	ctx.body = {
         // 通過(guò)讀取 failFiles 數(shù)組,即可展示是失敗的文件
		fail: `${ctx.req.failFiles}等文件上傳失敗`,
		flies: ctx.req.files
	}
})
app.use(uploadRouter.routes())
app.listen(8001, () => {
	console.log('koa server start success~')
})

我們發(fā)送請(qǐng)求看一下 uploads 文件下是否會(huì)增加新兩個(gè)文件,如下:

可以看到,符合類型的文件存儲(chǔ)成功,在看一下返回給客戶端的信息,如下:

現(xiàn)在就可以完美實(shí)現(xiàn)我們的需求,當(dāng)然三種方式需要結(jié)合具體業(yè)務(wù)場(chǎng)景使用,如果大家發(fā)現(xiàn)有更好的方式可以一起談?wù)?/p>

使用 jimp 對(duì)文件進(jìn)行不同大小的裁剪

為什么需要進(jìn)行不同大小的裁剪呢,在真實(shí)的開(kāi)發(fā)中,通常有些時(shí)候我們只需要展示一個(gè)預(yù)覽圖,也就是一張比較小的圖片,而不需要展示一張?jiān)瓐D,當(dāng)然這個(gè)圖片的展示可以由前端通過(guò)樣式限制,但是如果每次都返回一張?jiān)瓐D,那么請(qǐng)求壓力無(wú)疑會(huì)大一些,所以可以在上傳時(shí)就進(jìn)行不同大小的裁剪,在合適的請(qǐng)求返回對(duì)應(yīng)的圖片

這個(gè)庫(kù)的使用方式如下:

// 獲取圖片不同大小
const pictureResize = async (ctx, next) => {
	// 獲取所有圖像信息
	const files = ctx.req.files
	// 通過(guò) sharp/jimp 庫(kù)對(duì)圖片進(jìn)行裁剪
	for (const item of files) {
		// 通過(guò) Jimp.read(路徑) 讀取文件信息,并返回一個(gè)對(duì)象
		//  - 如果不希望使用同步的方法等待圖片處理,就可以使用 then 方法異步處理,處理圖片的時(shí)間還是比較長(zhǎng)的
		// 拼接寫入路徑
		// 獲取文件類型后綴
		const type = path.extname(item.filename)
		const filename = item.filename.replace(type, '')
		const url = path.join(item.destination, filename)
		Jimp.read(item.path).then(res => {
			// 通過(guò) resize 方法裁剪:參數(shù)一設(shè)置寬度,參數(shù)二:讓高度隨高度按比例裁剪
			// 在通過(guò) write 方法寫入,傳入寫入路徑即可
			//  - 并拼接后綴 large(大圖) middle(中等圖片) small(小圖)
			res.resize(1280, Jimp.AUTO).write(`${url}-large${type}`)
			res.resize(640, Jimp.AUTO).write(`${url}-middle${type}`)
			res.resize(320, Jimp.AUTO).write(`${url}-small${type}`)
		})
	}
	await next()
}
// 在接口處添加使用即可

來(lái)看一下 uploads 問(wèn)價(jià)下是否存儲(chǔ)了 原圖,大小中圖等不同的圖片,我在前端發(fā)送了兩張圖片,所以會(huì)有八張圖片,如下:

我們將圖片打開(kāi)對(duì)比看一下:

文件上傳錯(cuò)誤捕獲

  • 關(guān)于這個(gè)錯(cuò)誤捕獲官網(wǎng)中給出的例子是給 express 框架的,且是在 multer 的庫(kù)中,那難道就沒(méi)有辦法可以捕獲這個(gè)錯(cuò)誤了嗎,當(dāng)然老生常談的 trycatch 這里就不在討論,在 koa 框架中,中間件返回的是一個(gè) promise 對(duì)象,所以 koa-multer 這個(gè)庫(kù)自然也不能例外,返回的函數(shù)是 promise 類型
  • 所以根據(jù)這一點(diǎn),我們可以單獨(dú)的對(duì)這個(gè)方法進(jìn)行錯(cuò)誤捕獲,如下:
const captures = async (ctx, next) => {
	// 文件上傳錯(cuò)誤捕獲
    // 通過(guò)使用 then 和 catch 方法進(jìn)行捕獲,不理解的可以去補(bǔ)充一個(gè) promise 相關(guān)的知識(shí)
    //  - 限制文件上傳為 1
	let err = await upload
		.array('files', 2)(ctx, next)
		.then(res => res)
		.catch(err => err)
	if (err) {
		ctx.body = {
			msg: err.message
		}
	}
}
// 當(dāng)然,接口中的函數(shù)也需要更換
uploadRouter.post('/more', captures, (ctx, next) => {
	ctx.body = {
		fail: `${ctx.req.failFiles}等文件上傳失敗`,
		flies: ctx.req.files
	}
})

我們測(cè)試一下,當(dāng)限制數(shù)量為 2,上傳 3 個(gè)文件時(shí)的結(jié)果,看一下返回給客戶端的結(jié)果

再看一下后端程序有沒(méi)有崩潰

此方法是并沒(méi)有在官方文檔中給出,所以具體實(shí)現(xiàn)是否一定穩(wěn)定,還有待考究,如果大家有更好的方法,歡迎討論

源碼展示

當(dāng)然,可能演示時(shí)為了區(qū)別,和上面實(shí)例代碼會(huì)有一些變量名的差別,但是邏輯是一樣的,大家放心閱讀

// 引入內(nèi)置模塊
const path = require('path')
// 引入第三方庫(kù)
const Koa = require('koa')
const Router = require('koa-router')
const multer = require('koa-multer')
const Jimp = require('jimp')
// 創(chuàng)建app實(shí)例
const app = new Koa()
app.use(async (ctx, next)=>{
    ctx.req.failFiles = []
    await next()
})
// 創(chuàng)建路由實(shí)例
const uploadRouter = new Router({ prefix: '/upload' })
// 文件配置
const storage = multer.diskStorage({
	// 存儲(chǔ)路徑
	destination: (req, flie, cb) => {
		cb(null, './uploads')
	},
	// 設(shè)置文件名
	filename: (req, flie, cb) => {
		cb(null, Date.now() + path.extname(flie.originalname))
	}
})
// 限制上傳的文件
const limits = {
	fields: 10,
	fileSize: 104857600,
	files: 5
}
// 對(duì)上傳的文件進(jìn)行過(guò)濾
const fileFilter = (req, file, cb) => {
	const type = path.extname(file.originalname)
	if (type !== '.png') {
		cb(null, true)
	} else {
		req.failFiles.push(file.originalname)
		cb(null, false)
	}
}
// multer 方法會(huì)返回一個(gè)函數(shù),作為中間件
const upload = multer({ fileFilter, storage, limits })
// 對(duì)單文件上傳時(shí)出現(xiàn)的錯(cuò)誤進(jìn)行捕獲
const capture = async (ctx, next) => {
	let err = await upload
		.single('file')(ctx, next)
		.then(res => res)
		.catch(err => err)
	if (err) {
		ctx.body = {
			msg: err.message
		}
	}
}
// 對(duì)多文件上傳時(shí)出現(xiàn)的錯(cuò)誤進(jìn)行捕獲
const captures = async (ctx, next) => {
	let err = await upload
		.array('files')(ctx, next)
		.then(res => res)
		.catch(err => err)
	if (err) {
		ctx.body = {
			msg: err.message
		}
	}
}
// 對(duì)fields多文件上傳時(shí)出現(xiàn)的錯(cuò)誤進(jìn)行捕獲
const capturesFields = async (ctx, next) => {
	let err = await upload
		.fields([
			{ name: 'avatar', maxCount: 1 },
			{ name: 'files', maxCount: 3 }
		])(ctx, next)
		.then(res => res)
		.catch(err => err)
	if (err) {
		ctx.body = {
			msg: err.message
		}
	}
}
// 獲取圖片不同大小
const pictureResize = async (ctx, next) => {
	const files = ctx.req.files
	for (const item of files) {
		const type = path.extname(item.filename)
		const filename = item.filename.replace(type, '')
		const url = path.join(item.destination, filename)
		Jimp.read(item.path).then(res => {
			res.resize(1280, Jimp.AUTO).write(`${url}-large${type}`)
			res.resize(640, Jimp.AUTO).write(`${url}-middle${type}`)
			res.resize(320, Jimp.AUTO).write(`${url}-small${type}`)
		})
	}
	await next()
}
// 單文件上傳接口
uploadRouter.post('/', capture, (ctx, next) => {
	ctx.body = {
		flie: ctx.req.file
	}
})
// 多文件上傳接口
uploadRouter.post('/more', captures, pictureResize, (ctx, next) => {
	ctx.body = {
		text: ctx.req.body || '',
		fail: `${ctx.req.failFiles}等文件上傳失敗`,
		flies: ctx.req.files
	}
})
// 測(cè)試多文件上傳接口之 fields
uploadRouter.post('/fields', capturesFields, (ctx, next) => {
	ctx.body = {
		text: ctx.req.body || '',
		flies: ctx.req.files
	}
})
// 注冊(cè)接口
app.use(uploadRouter.routes())
// 監(jiān)聽(tīng)
app.listen(8001, () => {
	console.log('koa server start success~')
})

到此這篇關(guān)于在 node 中使用 koa-multer 庫(kù)上傳文件詳解的文章就介紹到這了,更多相關(guān)node使用 koa-multer 庫(kù)上傳文件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Node.js中的npm單獨(dú)與批量升級(jí)依賴包的方式超詳細(xì)講解

    Node.js中的npm單獨(dú)與批量升級(jí)依賴包的方式超詳細(xì)講解

    npm outdated僅檢查所有已安裝包的依賴關(guān)系,并將當(dāng)前版本遠(yuǎn)程倉(cāng)庫(kù)中的最新版本進(jìn)行對(duì)比,不會(huì)升級(jí),這篇文章主要介紹了Node.js中的npm單獨(dú)與批量升級(jí)依賴包的方式超詳細(xì)講解,需要的朋友可以參考下
    2024-02-02
  • node.js中的fs.futimesSync方法使用說(shuō)明

    node.js中的fs.futimesSync方法使用說(shuō)明

    這篇文章主要介紹了node.js中的fs.futimes方法使用說(shuō)明,本文介紹了fs.futimesSync方法說(shuō)明、語(yǔ)法、接收參數(shù)、使用實(shí)例和實(shí)現(xiàn)源碼,需要的朋友可以參考下
    2014-12-12
  • Node.js五大應(yīng)用性能技巧小結(jié)(必須收藏)

    Node.js五大應(yīng)用性能技巧小結(jié)(必須收藏)

    本篇文章主要介紹了Node.js五大應(yīng)用性能技巧小結(jié)(必須收藏),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家
    2017-08-08
  • nodejs?express實(shí)現(xiàn)中間件

    nodejs?express實(shí)現(xiàn)中間件

    這篇文章主要為大家介紹了nodejs?express實(shí)現(xiàn)中間件實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • Node.js控制臺(tái)彩色輸出的方法與原理實(shí)例詳解

    Node.js控制臺(tái)彩色輸出的方法與原理實(shí)例詳解

    這篇文章主要給大家介紹了關(guān)于Node.js控制臺(tái)彩色輸出的方法與原理的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Node.js具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • Node.js API詳解之 string_decoder用法實(shí)例分析

    Node.js API詳解之 string_decoder用法實(shí)例分析

    這篇文章主要介紹了Node.js API詳解之 string_decoder用法,結(jié)合實(shí)例形式分析了Node.js API中string_decoder的功能、用法及操作注意事項(xiàng),需要的朋友可以參考下
    2020-04-04
  • node.js express JWT token生成與校驗(yàn)的實(shí)現(xiàn)

    node.js express JWT token生成與校驗(yàn)的實(shí)現(xiàn)

    本文主要介紹了node.js express JWT token生成與校驗(yàn)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-12-12
  • node實(shí)現(xiàn)批量上傳本地圖片轉(zhuǎn)為圖片CDN的項(xiàng)目實(shí)踐

    node實(shí)現(xiàn)批量上傳本地圖片轉(zhuǎn)為圖片CDN的項(xiàng)目實(shí)踐

    本文主要介紹了node實(shí)現(xiàn)批量上傳本地圖片轉(zhuǎn)為圖片CDN的項(xiàng)目實(shí)踐,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • 基于node.js之調(diào)試器詳解

    基于node.js之調(diào)試器詳解

    下面小編就為大家?guī)?lái)一篇基于node.js之調(diào)試器詳解。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-08-08
  • Ubuntu 16.04 64位中搭建Node.js開(kāi)發(fā)環(huán)境教程

    Ubuntu 16.04 64位中搭建Node.js開(kāi)發(fā)環(huán)境教程

    如果想要在Ubuntu 16.04上安裝Node.js的話,這篇文章對(duì)你來(lái)說(shuō)肯定很重要。Node.js從本質(zhì)上來(lái)說(shuō)就是一個(gè)運(yùn)行在服務(wù)端上的封裝好了輸入輸出流的javascript程序。本文給大家詳細(xì)介紹了在Ubuntu 16.04 64位搭建Node.js開(kāi)發(fā)環(huán)境的步驟,有需要的朋友們可以參考學(xué)習(xí)。
    2016-10-10

最新評(píng)論