vue3+koa實(shí)現(xiàn)文件上傳功能的全過程記錄
前言:
在完成自己的畢設(shè)中,需要引入文件上傳,前后找到資料實(shí)現(xiàn)了圖片上傳,在此做一個(gè)總結(jié)
技術(shù)引用:
1. 使用了 koa-body 實(shí)現(xiàn)后臺文件上傳功能
2. 使用了 koa-static 實(shí)現(xiàn)后臺資源靜態(tài)訪問
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ā)送接口請求的響應(yīng)的回調(diào)函數(shù)
:headers="{ Authorization: headers }" // 向請求頭攜帶字段,因?yàn)槲疫@里使用了Token,需要在請求前攜帶Authorization
accept="image/jpeg,image/png"http://接受的文件類型方便挑選。handleSuccess 方法的第一哥參數(shù)response就是訪問/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;
};后臺實(shí)現(xiàn):
引入koa-body,并注冊中間件:
app.use(koabody({
multipart: true, //開啟文件上傳
formidable: { // 路徑配置
// 在配置選項(xiàng)option 不推薦使用相對路徑
uploadDir: path.join(__dirname, './upload'), //配置保存路徑
keepExtensions: true //保存文件擴(kuò)展名
}
}))在配置完koa-body 后,就可以通過 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('上傳出錯')
}
// ctx.body = util.success(ctx.request.files.file.path, "上傳成功")
})引入koa-static 進(jìn)行靜態(tài)資源訪問
app.use(koaStatic(path.join(__dirname, './upload')))//開啟靜態(tài)資源訪問
之后,./upload文件下就是靜態(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")我們在渲染列表的時(shí)候,就已經(jīng)得到了所有信息,現(xiàn)在只需要點(diǎn)擊查看回顯信息而已
const handleView = (row) => {
action.value = "view"; // 設(shè)置action狀態(tà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;
};效果如下:


遇到的問題:
已解決:
Token驗(yàn)證問題:
因?yàn)槲胰旨尤肓私涌谛r?yàn),導(dǎo)致在最初的時(shí)候我upload 的結(jié)果一致倒是400,未加入Token,并且在訪問的時(shí)候也是一致報(bào)Token問題,這是倆個(gè)問題。在上傳時(shí)候,是需要Token,也就是通過:header屬性添加Authorazation。但是訪問的時(shí)候報(bào)錯,是因?yàn)槲覀冊L問靜態(tài)資源的時(shí)候也是接口訪問,需要在后臺加上這段代碼:對一些不需要的token進(jìn)行的接口攔截放過,例如/api下的login接口,和非api開頭的所有接口,也就是我們訪問靜態(tài)資源的接口。
app.use(koajwt({ secret: 'secret' }).unless({
// 過略一些不需要token的接口
// 過略掉除了 登錄接口 和 非api接口(主要為靜態(tài)資源請求接口)
path: [/^\/api\/users\/login/, /^((?!\/api).)*$/],
})) // 使用中間件進(jìn)行token攔截proxy代理問題:
在vue3 cli 的配置下,配置了proxy代理:這樣訪問以/api的接口都會跳轉(zhuǎn)到/localhost:3000/api下。
proxy: {
//攔截以api開始的請求,將/api 替換成http://localhost:3000, 瀏覽器同源策略,無法在前端 port:8080 訪問后端 prot:3000 端口,需要借助代理攔截請求,進(jìn)行接口轉(zhuǎn)發(fā)
"/api": {
target: "http://localhost:3000"
}
}但現(xiàn)在我有一個(gè)問題,我們之前說到文件靜態(tài)資源通過http://localhost:3000/upload_f16d68210c6822f1000ce11f363f0815.jpg 來訪問,這個(gè)路徑按上述思路配置代理:會導(dǎo)致前端路由也一起訪問后端接口,導(dǎo)致一鍋粥,這樣是不對的。
"/": {
target: "http://localhost:3000"
},最后只能采取死辦法,引入koa-cors 實(shí)現(xiàn)后臺跨域,并且通過絕對路徑: url: "http://localhost:3000/"+ data.imgPath.imgBathPath,來訪問。
總結(jié):
本次完成畢設(shè)遇到的問題都是通過查看文檔 + 百度查詢的方式,當(dāng)然這些方法在腦海里也有大致的印象,這次做一個(gè)總結(jié)。
到此這篇關(guān)于vue3+koa實(shí)現(xiàn)文件上傳功能的文章就介紹到這了,更多相關(guān)vue3+koa文件上傳功能內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue-cli搭建spa項(xiàng)目的項(xiàng)目實(shí)踐
本文主要介紹了Vue-cli搭建spa項(xiàng)目的項(xiàng)目實(shí)踐,首先,你需要安裝Vue CLI,然后通過它創(chuàng)建新項(xiàng)目,接著,選擇和配置適當(dāng)?shù)牟寮鸵蕾図?xiàng),以完善你的SPA項(xiàng)目,感興趣的可以了解一下2023-09-09
vue實(shí)現(xiàn)接口封裝的實(shí)現(xiàn)示例
本文主要介紹了vue實(shí)現(xiàn)接口封裝的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-11-11
Vue?axios和vue-axios的關(guān)系及使用區(qū)別
axios是基于promise的HTTP庫,可以使用在瀏覽器和node.js中,它不是vue的第三方插件,vue-axios是axios集成到Vue.js的小包裝器,可以像插件一樣安裝使用:Vue.use(VueAxios, axios),本文給大家介紹Vue?axios和vue-axios關(guān)系,感興趣的朋友一起看看吧2022-08-08
前端vue3打印功能實(shí)現(xiàn)(多頁打印、不使用插件)
在Vue項(xiàng)目中實(shí)現(xiàn)打印功能是前端開發(fā)中常見需求之一,這篇文章主要介紹了前端vue3打印功能實(shí)現(xiàn)的全部過程,文中介紹的方法實(shí)現(xiàn)了多頁打印并且不使用插件,需要的朋友可以參考下2024-09-09
VueJs單頁應(yīng)用實(shí)現(xiàn)微信網(wǎng)頁授權(quán)及微信分享功能示例
本篇文章主要介紹了VueJs單頁應(yīng)用實(shí)現(xiàn)微信網(wǎng)頁授權(quán)及微信分享功能示例,具有一定的參考價(jià)值,有興趣的可以了解一下2017-07-07
vue-cli3自動消除console.log()的調(diào)試信息方式
這篇文章主要介紹了vue-cli3自動消除console.log()的調(diào)試信息方式,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-10-10

