前言:
圖片上傳算是一個蠻常見的功能,基本上是一個網站,不管是後台還是前台基本上是都會有這項功能的。
這篇文章主要講解後端圖片處理的部分。
之後會介紹前端圖片裁切套件。
安裝
npm i multer
官網範例
const express = require('express')
const multer = require('multer')
const upload = multer({ dest: 'uploads/' })
const app = express()
app.post('/profile', upload.single('avatar'), function (req, res, next) {
// 單筆
// req.file is the `avatar` file
// req.body will hold the text fields, if there were any
})
app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) {
// 多筆
// req.files is array of `photos` files
// req.body will contain the text fields, if there were any
})
const cpUpload = upload.fields([{ name: 'avatar', maxCount: 1 }, { name: 'gallery', maxCount: 8 }])
app.post('/cool-profile', cpUpload, function (req, res, next) {
// middleware的方式
// req.files is an object (String -> Array) where fieldname is the key, and the value is array of files
//
// e.g.
// req.files['avatar'][0] -> File
// req.files['gallery'] -> Array
//
// req.body will contain the text fields, if there were any
})
注意事項
- Multer 的 前端 Request 只能用 form-data 的方式推送 header 記得塞入
multipart/form-data
- Express 記得啟用 form-data 的方式 記得
app.use('body-parser') // body-parser 是 Express 解析 request 的套件
- 如果上傳大小相對大的文件使用
multer.memoryStorage()
注意會導致 Memory 不足 - 若是 使用
multer.memoryStorage()
Multer 推送 Buffer 結束 Request 會將 Memory 釋放
multer with gcs - by TS
使用 Multer 上傳至 GCS,簡單來說也是透過 multer 再處理 Buffer 至 GCS
// 封裝的 GCS Package TS
imort { Storage, Bucket } from '@google-cloud/storage';
export type GcsFileUploadResult = {
message?: string // 訊息
filename?: Array<string> // 檔案名稱
};
export class GCS {
private storage: Storage
private bucket: Bucket
constructor(bucket) {
this.storage = new Storage({ keyFilename: process.env.GCP_AUTH_LOCATION }) // GCP_AUTH_LOCATION - GCP AUTH JSON key
this.bucket = storage.bucket(process.env.GCS_BUCKETNAME) // GCS_BUCKETNAME - GCS Bucket Name
}
/**
* 上傳
* @param {Express.Multer.File} file 檔案
* @param {string} name 檔名 ex: xxx.jpg
* @param {Promise<GcsFileUploadResult>}
*/
private upload(file: Express.Multer.File, name: string): Promise<GcsFileUploadResult> {
return new Promise((resolve, reject) => {
const blob = this.bucket.file(name);
const blobStream = blob.createWriteStream();
blobStream
.on('finish', () => resolve({ message: '上傳成功', filename: [name] }));
.on('error', () => reject({ message: '上傳失敗', filename: [name] }));
blobStream.end(file.buffer);
})
}
/**
* 上傳至GCS
* @param {Express.Multer.File} file 檔案
* @param {string} name 檔名 ex: xxx.jpg
* @param {Promise<GcsFileUploadResult>}
*/
uploadToGCS(file: Express.Multer.File, name: string): Promise<GcsFileUploadResult> {
let result: GcsFileUploadResult;
try { result = await this.upload(file, name) };
catch (err) { result.message = '檔案上傳失敗' };
return result;
}
}