技術棧
後端:
npm i koa koa-router koa-multer koa-static -S
前端:vue、element-ui
前端代碼片段
<template>
<div>
<!-- element-ui 上傳元件,action為接口位址,接口預設同域或已做跨域處理 -->
<el-upload
class="upload"
action="/api/upload"
:on-success="handleUploadSuccess"
:limit="1"
>
<el-button size="small" type="primary">點選上傳</el-button>
</el-upload>
<img :src="imageObjectUrl" alt="" />
<img :src="imageOnlineUrl" alt="" />
</div>
</template>
<script>
export default {
data() {
return {
imageObjectUrl: "", // 純前端預覽圖檔位址
imageOnlineUrl: "", // 後端傳回的真實圖檔位址
};
},
methods: {
handleUploadSuccess(res, file) {
this.imageObjectUrl = URL.createObjectURL(file.raw);
this.imageOnlineUrl = res.path;
},
},
};
</script>
後端代碼邏輯
- 在後端項目跟路徑下建立
檔案夾,利用static
将koa-static
檔案夾配成靜态資源通路目錄static
// serve/src/app.js
import Koa from 'koa';
import koaStatic from 'koa-static';
app.use(koaStatic('./static'))
- 在
檔案夾建立static
檔案夾,作為檔案的儲存目錄uploads
- 編寫
上傳接口/api/upload
// server/src/router/upload.js
import KoaRouter from 'koa-router';
import multer from 'koa-multer'
// 自定義檔案儲存處理器
const storage = multer.diskStorage({
destination: function (req, file, cb) { // 上傳檔案的儲存位址
cb(null, 'static/uploads/')
},
filename: function (req, file, cb) { // 自定義上傳的檔案名稱
const singfileArray = file.originalname.split('.');
const fileExtension = singfileArray[singfileArray.length - 1];
cb(null, Date.now() + "." + fileExtension);
}
})
// 初始化上傳檔案中間件
const upload = multer({ storage: storage })
// 後端路由配置
const uploadRoute = new KoaRouter({
prefix: '/api/upload'
});
uploadRoute.post('/', upload.single('file'), async (ctx) => {
const { headers, file } = ctx.req;
ctx.body = {
path: 'http://' + headers.host + '/uploads/' + file.filename, // 拼接成完整的圖檔位址
message: 'ok'
};
})
export {
uploadRoute
}
- 注冊
路由uploadRoute
// server/src/routers/index.js
import combineRouters from 'koa-combine-routers';
import { uploadRoute } from './upload.js';
const router = combineRouters(uploadRoute);
export default router;