vue3+koa實(shí)現(xiàn)文件上傳功能的全過(guò)程記錄
前言:
在完成自己的畢設(shè)中,需要引入文件上傳,前后找到資料實(shí)現(xiàn)了圖片上傳,在此做一個(gè)總結(jié)
技術(shù)引用:
1. 使用了 koa-body 實(shí)現(xiàn)后臺(tái)文件上傳功能
2. 使用了 koa-static 實(shí)現(xiàn)后臺(tái)資源靜態(tài)訪問(wèn)
3. 使用了 Element plus UI的upload組件實(shí)現(xiàn)前端文件上傳
前端實(shí)現(xiàn)
代碼實(shí)現(xiàn):
<el-upload
v-model:file-list="fileList"
class="upload-demo"
action="/api/article/upload"
:limit="1"
:on-remove="handleRemove"
:on-change="handlePreview"
:on-success="handleSuccess"
list-type="picture"
:headers="{ Authorization: headers }"
accept="image/jpeg,image/png"
>
<el-button type="primary">Click to upload</el-button>
<template #tip>
<div class="el-upload__tip">
jpg/png files with a size less than 500kb
</div>
</template>
</el-upload>其中介紹幾個(gè)重要的需要用到的屬性:
action="/api/article/upload" // 向該目錄下發(fā)送接口
:on-remove="handleRemove" //刪除圖片觸發(fā)的回調(diào)事件
:on-change="handlePreview" //觸發(fā)圖片新增之類的修改觸發(fā)的回調(diào)事件
:on-success="handleSuccess" //向action路徑下發(fā)送接口請(qǐng)求的響應(yīng)的回調(diào)函數(shù)
:headers="{ Authorization: headers }" // 向請(qǐng)求頭攜帶字段,因?yàn)槲疫@里使用了Token,需要在請(qǐng)求前攜帶Authorization
accept="image/jpeg,image/png"http://接受的文件類型方便挑選。handleSuccess 方法的第一哥參數(shù)response就是訪問(wèn)/api/article/upload后的響應(yīng)結(jié)果,這個(gè)結(jié)果就是我們將圖片放在靜態(tài)資源目錄的基本地址basePath,我這邊 封裝了一下, imgPath的結(jié)果如下: { imgBathPath:upload_4f60af0c9732ab4a1463e29c4bbc8c04.jpg, imgName:"xxxx"},擁有圖片的地址和圖片名字,用于查看時(shí)候的回顯。

const handleSuccess = (response) => {
console.log(response.data, "--------");
imgPath.value = response.data;
};后臺(tái)實(shí)現(xiàn):
引入koa-body,并注冊(cè)中間件:
app.use(koabody({
multipart: true, //開(kāi)啟文件上傳
formidable: { // 路徑配置
// 在配置選項(xiàng)option 不推薦使用相對(duì)路徑
uploadDir: path.join(__dirname, './upload'), //配置保存路徑
keepExtensions: true //保存文件擴(kuò)展名
}
}))在配置完koa-body 后,就可以通過(guò) const { file } = ctx.request.files; 拿到本次文件上傳的圖片的一些信息。再進(jìn)行后端檢驗(yàn),只接受圖片類型文件的上傳,不然返回失?。?/p>
router.post('/upload', async (ctx) => {
// console.log(ctx.request.files, "ctx.request.files")
const { file } = ctx.request.files;
const fileTypes = ["image/jpeg", "image/png"]
if (file) {
if (fileTypes.includes(file.type)) {
ctx.body = util.success({ imgName: file.name, imgBathPath: path.basename(file.path) }, "上傳成功")
} else {
ctx.body = util.fail("上傳圖片非jpg 和 png 格式")
}
} else {
ctx.body = util.fail('上傳出錯(cuò)')
}
// ctx.body = util.success(ctx.request.files.file.path, "上傳成功")
})引入koa-static 進(jìn)行靜態(tài)資源訪問(wèn)
app.use(koaStatic(path.join(__dirname, './upload')))//開(kāi)啟靜態(tài)資源訪問(wèn)
之后,./upload文件下就是靜態(tài)資源了,我們可以直接訪問(wèn),如:

前臺(tái)回顯圖片:
首先我們接口返回的數(shù)據(jù)結(jié)果如下:
const mongoose = require('mongoose')
const articleSchema = mongoose.Schema({
articleTitle: String, // 文章標(biāo)題
articleType: String, // 文章類型
articleContent: String, // 內(nèi)容,富文本
publishState: Number, // 發(fā)布狀態(tài) 0 未發(fā)布 1 已發(fā)布 2已刪除
articleAuth: String,
imgPath: {
imgName: String,
imgBathPath: String,
},
applyUser: {
userId: String,
userName: String,
userEmail: String
},
publishTime: { type: Date, },
createTime: { type: Date, default: Date.now } // 創(chuàng)建事件
})
module.exports = mongoose.model("article", articleSchema, "article")我們?cè)阡秩玖斜淼臅r(shí)候,就已經(jīng)得到了所有信息,現(xiàn)在只需要點(diǎn)擊查看回顯信息而已
const handleView = (row) => {
action.value = "view"; // 設(shè)置action狀態(tài),用來(lái)判斷disable條件
let data = { ...row }; //遍歷彈窗數(shù)據(jù)
// 將文本編輯器設(shè)置為只讀
// const editor = editorRef.value;
// editor.disable();
// 填充富文本到富文本編輯器中
articleContent.value = data.articleContent;
// 處理圖片的回顯
const temp = {
name: data.imgPath.imgName,
url: "http://localhost:3000/" + data.imgPath.imgBathPath,
};
fileList.value.push(temp);
console.log(fileList.value, "fileList.value");
articleForm.value = data;
showModal.value = true;
};效果如下:


遇到的問(wèn)題:
已解決:
Token驗(yàn)證問(wèn)題:
因?yàn)槲胰旨尤肓私涌谛r?yàn),導(dǎo)致在最初的時(shí)候我upload 的結(jié)果一致倒是400,未加入Token,并且在訪問(wèn)的時(shí)候也是一致報(bào)Token問(wèn)題,這是倆個(gè)問(wèn)題。在上傳時(shí)候,是需要Token,也就是通過(guò):header屬性添加Authorazation。但是訪問(wèn)的時(shí)候報(bào)錯(cuò),是因?yàn)槲覀冊(cè)L問(wèn)靜態(tài)資源的時(shí)候也是接口訪問(wèn),需要在后臺(tái)加上這段代碼:對(duì)一些不需要的token進(jìn)行的接口攔截放過(guò),例如/api下的login接口,和非api開(kāi)頭的所有接口,也就是我們?cè)L問(wèn)靜態(tài)資源的接口。
app.use(koajwt({ secret: 'secret' }).unless({
// 過(guò)略一些不需要token的接口
// 過(guò)略掉除了 登錄接口 和 非api接口(主要為靜態(tài)資源請(qǐng)求接口)
path: [/^\/api\/users\/login/, /^((?!\/api).)*$/],
})) // 使用中間件進(jìn)行token攔截proxy代理問(wèn)題:
在vue3 cli 的配置下,配置了proxy代理:這樣訪問(wèn)以/api的接口都會(huì)跳轉(zhuǎn)到/localhost:3000/api下。
proxy: {
//攔截以api開(kāi)始的請(qǐng)求,將/api 替換成http://localhost:3000, 瀏覽器同源策略,無(wú)法在前端 port:8080 訪問(wèn)后端 prot:3000 端口,需要借助代理攔截請(qǐng)求,進(jìn)行接口轉(zhuǎn)發(fā)
"/api": {
target: "http://localhost:3000"
}
}但現(xiàn)在我有一個(gè)問(wèn)題,我們之前說(shuō)到文件靜態(tài)資源通過(guò)http://localhost:3000/upload_f16d68210c6822f1000ce11f363f0815.jpg 來(lái)訪問(wèn),這個(gè)路徑按上述思路配置代理:會(huì)導(dǎo)致前端路由也一起訪問(wèn)后端接口,導(dǎo)致一鍋粥,這樣是不對(duì)的。
"/": {
target: "http://localhost:3000"
},最后只能采取死辦法,引入koa-cors 實(shí)現(xiàn)后臺(tái)跨域,并且通過(guò)絕對(duì)路徑: url: "http://localhost:3000/"+ data.imgPath.imgBathPath,來(lái)訪問(wèn)。
總結(jié):
本次完成畢設(shè)遇到的問(wèn)題都是通過(guò)查看文檔 + 百度查詢的方式,當(dāng)然這些方法在腦海里也有大致的印象,這次做一個(gè)總結(jié)。
到此這篇關(guān)于vue3+koa實(shí)現(xiàn)文件上傳功能的文章就介紹到這了,更多相關(guān)vue3+koa文件上傳功能內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue-cli-service不是內(nèi)部或外部命令,也不是可運(yùn)行的程序或批處理文件問(wèn)題
在Vue項(xiàng)目構(gòu)建過(guò)程中,如果遇到無(wú)法識(shí)別'vue-cli-service'命令的錯(cuò)誤提示,通常是因?yàn)闆](méi)有全局安裝vue-cli,解決這個(gè)問(wèn)題的步驟主要包括:首先檢查Vue版本,如果未安裝則先安裝Vue;其次全局安裝vue-cli;若在安裝過(guò)程中遇到cnpm命令找不到的情況2024-10-10
vue使用echarts實(shí)現(xiàn)水平柱形圖實(shí)例
這篇文章主要介紹了vue使用echarts實(shí)現(xiàn)水平柱形圖實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-09-09
elementui之el-table-column日期格式顯示方式
文章介紹了如何使用formatter屬性對(duì)表格某一列的內(nèi)容進(jìn)行日期格式化,通過(guò)綁定日期格式化的方法實(shí)現(xiàn),展示了前端代碼的模板和方法,并給出了前端效果的展示2024-12-12
前端vue2?element?ui高效配置化省時(shí)又省力
這篇文章主要為大家介紹了前端高效配置化vue2?element?ui省時(shí)又省力,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07

