vue3+koa實(shí)現(xiàn)文件上傳功能的全過程記錄
前言:
在完成自己的畢設(shè)中,需要引入文件上傳,前后找到資料實(shí)現(xiàn)了圖片上傳,在此做一個總結(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>
其中介紹幾個重要的需要用到的屬性:
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é)果,這個結(jié)果就是我們將圖片放在靜態(tài)資源目錄的基本地址basePath,我這邊 封裝了一下, imgPath的結(jié)果如下: { imgBathPath:upload_4f60af0c9732ab4a1463e29c4bbc8c04.jpg, imgName:"xxxx"},擁有圖片的地址和圖片名字,用于查看時候的回顯。
const handleSuccess = (response) => { console.log(response.data, "--------"); imgPath.value = response.data; };
后臺實(shí)現(xiàn):
引入koa-body,并注冊中間件:
app.use(koabody({ multipart: true, //開啟文件上傳 formidable: { // 路徑配置 // 在配置選項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")
我們在渲染列表的時候,就已經(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)致在最初的時候我upload 的結(jié)果一致倒是400,未加入Token,并且在訪問的時候也是一致報Token問題,這是倆個問題。在上傳時候,是需要Token,也就是通過:header屬性添加Authorazation。但是訪問的時候報錯,是因?yàn)槲覀冊L問靜態(tài)資源的時候也是接口訪問,需要在后臺加上這段代碼:對一些不需要的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)在我有一個問題,我們之前說到文件靜態(tài)資源通過http://localhost:3000/upload_f16d68210c6822f1000ce11f363f0815.jpg 來訪問,這個路徑按上述思路配置代理:會導(dǎo)致前端路由也一起訪問后端接口,導(dǎo)致一鍋粥,這樣是不對的。
"/": { target: "http://localhost:3000" },
最后只能采取死辦法,引入koa-cors 實(shí)現(xiàn)后臺跨域,并且通過絕對路徑: url: "http://localhost:3000/"+ data.imgPath.imgBathPath,來訪問。
總結(jié):
本次完成畢設(shè)遇到的問題都是通過查看文檔 + 百度查詢的方式,當(dāng)然這些方法在腦海里也有大致的印象,這次做一個總結(jié)。
到此這篇關(guān)于vue3+koa實(shí)現(xiàn)文件上傳功能的文章就介紹到這了,更多相關(guān)vue3+koa文件上傳功能內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue實(shí)現(xiàn)接口封裝的實(shí)現(xiàn)示例
本文主要介紹了vue實(shí)現(xiàn)接口封裝的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-11-11Vue?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項目中實(shí)現(xiàn)打印功能是前端開發(fā)中常見需求之一,這篇文章主要介紹了前端vue3打印功能實(shí)現(xiàn)的全部過程,文中介紹的方法實(shí)現(xiàn)了多頁打印并且不使用插件,需要的朋友可以參考下2024-09-09VueJs單頁應(yīng)用實(shí)現(xiàn)微信網(wǎng)頁授權(quán)及微信分享功能示例
本篇文章主要介紹了VueJs單頁應(yīng)用實(shí)現(xiàn)微信網(wǎng)頁授權(quán)及微信分享功能示例,具有一定的參考價值,有興趣的可以了解一下2017-07-07vue-cli3自動消除console.log()的調(diào)試信息方式
這篇文章主要介紹了vue-cli3自動消除console.log()的調(diào)試信息方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-10-10