当前位置:   article > 正文

vue3 element-plus el-upload的使用及携带token通过koa-jwt认证和携带cookie session通过koa-session认证的设置_elementplus el-upload headers

elementplus el-upload headers

node.js后端服务器配置了koa-session和koa-jwt双重认证,而前端el-upload中的action只是个url,如果没有配置header会导致上传文件失败,诸如“The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'.”错误

注:使用el-upload时,node.js后端需用使用koa-body,不要和koa-bodyparser同时使用。

以下是项目中一个关于上传PDF使用el-upload的例子,仅实现了通过koa-jwt认证,但未通过koa-session认证。(koa-session解决办法:后端服务器针对上传文件的api进行白名单放行)

vue3 el-upload页面效果动态

vue3>src>components>pdf>pathFetch.vue:template

drag:可拖放上传文件

multiple:允许上传多个文件

method:上传方式,默认的是post,其实可以不用定义

action:后端api接口,通过这种方式来访问api容易是容易,但没考虑到后端服务器认证的问题,可以设置with-credentials来携带cookie中的session,但这是个坑我爬了半天没爬出来……,element-plus官网还介绍了http-request接口,但我觉得更坑,各种尝试都没法通过koa-session认证。

headers:设置请求头部,在这里设置Authorization可以通过koa-jwt认证,这点个赞

auto-upload:是否自动上传,默认是自动上传的,最好是改成手动

on-success:上传成功的回调函数,这是个好东西

  1. <template>
  2. <el-upload ref="uploadRef" drag multiple method="post" action="http://192.168.8.120:8802/api/mongo/upload/pdf"
  3. :headers="headersObj" :auto-upload="false" :on-success="uploadSuccess" :on-error="uploadError">
  4. <el-icon>
  5. <upload-filled />
  6. </el-icon>
  7. <div class="upload-text">
  8. 将文件拖入,<em>或者点击上传</em>
  9. </div>
  10. <template #tip>
  11. <div class="upload-tip">
  12. 一次性不要拖入太多PDF文件,仅识别PDF文件
  13. </div>
  14. <div class="pdf-parser">
  15. <el-button type="primary" size="small" @click="submitUpload">开始上传</el-button>
  16. </div>
  17. </template>
  18. </el-upload>
  19. </template>

vue3>src>components>pdf>pathFetch.vue>template:script

注:未展示pinia pdfStore部分代码

  1. <script setup lang='ts'>
  2. import { ref } from "vue"
  3. import { ElMessage } from "element-plus"
  4. import 'element-plus/es/components/message/style/css'
  5. import { pdfStore } from "@/pinia/pdfStore"
  6. const usePdfStore = pdfStore()
  7. const uploadRef: any = ref(null)
  8. const submitUpload = async () => {
  9. await uploadRef.value?.submit() // 手动上传PDF文件
  10. usePdfStore.getRenameList() // 获取下一步的映射表
  11. }
  12. const uploadSuccess = () => {
  13. usePdfStore.isUpload = true // el-upload回调:上传成功标识为true
  14. ElMessage({
  15. message: '上传PDF文件成功!',
  16. type: 'success'
  17. })
  18. }
  19. const uploadError = () => {
  20. return ElMessage({
  21. message: '上传PDF文件失败!', // el-upload回调:上传失败提示错误
  22. type: 'error'
  23. })
  24. }
  25. const headersObj = {
  26. "Authorization": 'Bearer ' + localStorage.getItem('token'), // JWT认证,携带token
  27. }

node.js>app.js>koa-body安装使用

基础使用见官网:https://www.npmjs.com/package/koa-body

  1. const fs = require('fs')
  2. const {koaBody} = require('koa-body') // 解析文件,对应前端的file
  3. const { v4:uuidv4 } = require('uuid')
  4. // 使用第三方中间件:解析挂载请求body
  5. // 注意:在routes之前使用
  6. // 注意:session和JWT通过后才会到这里
  7. // app.use(bodyParser({multipart:true})) // 注意要设置multipart,接收FormData()
  8. app.use(koaBody({
  9. multipart:true, // 支持文件上传
  10. formidable:{
  11. uploadDir:path.join(__dirname, './upload'), // 文件保存路径,对应file.filepath,注意要先创建对应文件夹否则不生效?
  12. keepExtensions:true, // 保留文件扩展名
  13. maxFieldsSize:50*1024*1024, // 限制50M
  14. multiples:true, // 允许上传多个文件
  15. onFileBegin:(name, file) => {
  16. // const subPath = uuidv4() // 生成一个随机字符串
  17. // fs.mkdirSync(path.join(__dirname, './upload/', `${subPath}`))
  18. // fs.path = path.join(__dirname, './upload/', `${subPath}`) // 定义一个
  19. // console.log('app.js koa-body onFileBegin subPath:', subPath)
  20. file.filepath = path.join(__dirname, './upload/', file.originalFilename)// 上传前的回调函数,比如重新设置路径
  21. // file.filepath = path.join(__dirname, './upload/', `${subPath}/`, file.originalFilename)// 上传前的回调函数,比如重新设置路径
  22. console.log('app.js koa-body onFileBegin file:', file)
  23. },
  24. onError: (err) => {
  25. appendErrorLog('app.js koa-body onError:',err) // 调用工具,将错误写入错误日志文件
  26. }
  27. },
  28. textLimit:'10mb',
  29. jsonLimit:'20mb',
  30. encoding:'utf-8',
  31. parsedMethods:['GET', 'POST', 'PUT', 'DELETE'],
  32. extendTypes:{
  33. 'text/plain':['txt'], // 括号内是文件扩展名
  34. 'application/pdf':['pdf']
  35. }
  36. }))

node.js>app.js>session放行

with-credential这个坑实在爬不动了,放行吧……

  1. // session拦截:有必要吗?
  2. app.use((ctx, next) => {
  3. // ignore login isLogin:方向
  4. const ignorePath = [
  5. '/api/login',
  6. '/api/isLogin',
  7. '/api/mongo/account/login',
  8. '/api/mongo/account/register',
  9. ]
  10. if (ignorePath.includes(ctx.path) || ctx.path.includes('upload')) {
  11. return next()
  12. }
  13. // session已登录:放行
  14. if (ctx.session.isLogin) {
  15. return next()
  16. }
  17. ctx.body = {
  18. status:201,
  19. message:'session过期,请重新登录!'
  20. }
  21. })

node.js>router>index.js:api

koa-body解析成功后,可以通过ctx.request.files来读取文件信息,注意只是信息不是内容,例如文件名、文件存放路径等信息

  1. router.post('/mongo/upload/pdf', async (ctx) => {
  2. try {
  3. // console.log('router mongo upload pdf files:', ctx.request.files)
  4. return ctx.body = {
  5. status: 200,
  6. message: '上传文件成功!'
  7. }
  8. } catch (error) {
  9. throw(error)
  10. }
  11. })

完结!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/283633
推荐阅读
相关标签
  

闽ICP备14008679号