vue3+koa实现文件上传功能的全过程记录

 更新时间:2023年01月04日 09:46:24   作者:大四小菜鸡  
开发项目的时候,用到文件上传的功能很常见,包括单文件上传和多文件上传,下面这篇文章主要给大家介绍了关于vue3+koa实现文件上传功能的相关资料,需要的朋友可以参考下

前言:

在完成自己的毕设中,需要引入文件上传,前后找到资料实现了图片上传,在此做一个总结

技术引用:

  1. 使用了 koa-body 实现后台文件上传功能

  2. 使用了 koa-static 实现后台资源静态访问

  3. 使用了 Element plus UI的upload组件实现前端文件上传

前端实现

代码实现:

     <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" // 向该目录下发送接口 
 :on-remove="handleRemove"   //删除图片触发的回调事件
 :on-change="handlePreview"  //触发图片新增之类的修改触发的回调事件
 :on-success="handleSuccess" //向action路径下发送接口请求的响应的回调函数
 :headers="{ Authorization: headers }" // 向请求头携带字段,因为我这里使用了Token,需要在请求前携带Authorization
 accept="image/jpeg,image/png"//接受的文件类型方便挑选。

handleSuccess 方法的第一哥参数response就是访问/api/article/upload后的响应结果,这个结果就是我们将图片放在静态资源目录的基本地址basePath,我这边 封装了一下, imgPath的结果如下: { imgBathPath:upload_4f60af0c9732ab4a1463e29c4bbc8c04.jpg, imgName:"xxxx"},拥有图片的地址和图片名字,用于查看时候的回显。

   const handleSuccess = (response) => { 
      console.log(response.data, "--------");
      imgPath.value = response.data;
    };

后台实现:

引入koa-body,并注册中间件:

app.use(koabody({
  multipart: true, //开启文件上传 
  formidable: { // 路径配置
    // 在配置选项option 不推荐使用相对路径
    uploadDir: path.join(__dirname, './upload'),  //配置保存路径
    keepExtensions: true //保存文件扩展名
  }
}))

在配置完koa-body 后,就可以通过 const { file } = ctx.request.files; 拿到本次文件上传的图片的一些信息。再进行后端检验,只接受图片类型文件的上传,不然返回失败:

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 进行静态资源访问

app.use(koaStatic(path.join(__dirname, './upload')))//开启静态资源访问

之后,./upload文件下就是静态资源了,我们可以直接访问,如:

前台回显图片:

首先我们接口返回的数据结果如下:

const mongoose = require('mongoose')
const articleSchema = mongoose.Schema({
    articleTitle: String,   // 文章标题
    articleType: String,   // 文章类型
    articleContent: String, // 内容,富文本
    publishState: Number,  // 发布状态 0 未发布 1 已发布 2已删除
    articleAuth: String,
    imgPath: {
        imgName: String,
        imgBathPath: String,
    },
    applyUser: {
        userId: String,
        userName: String,
        userEmail: String
    },
    publishTime: { type: Date, },
    createTime: { type: Date, default: Date.now } // 创建事件
})

module.exports = mongoose.model("article", articleSchema, "article")

我们在渲染列表的时候,就已经得到了所有信息,现在只需要点击查看回显信息而已

  const handleView = (row) => {
      action.value = "view"; // 设置action状态,用来判断disable条件
      let data = { ...row }; //遍历弹窗数据

      // 将文本编辑器设置为只读
      // 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验证问题:

因为我全局加入了接口校验,导致在最初的时候我upload 的结果一致倒是400,未加入Token,并且在访问的时候也是一致报Token问题,这是俩个问题。在上传时候,是需要Token,也就是通过:header属性添加Authorazation。但是访问的时候报错,是因为我们访问静态资源的时候也是接口访问,需要在后台加上这段代码:对一些不需要的token进行的接口拦截放过,例如/api下的login接口,和非api开头的所有接口,也就是我们访问静态资源的接口。

app.use(koajwt({ secret: 'secret' }).unless({
  // 过略一些不需要token的接口
  // 过略掉除了 登录接口 和 非api接口(主要为静态资源请求接口)
  path: [/^\/api\/users\/login/, /^((?!\/api).)*$/],

})) // 使用中间件进行token拦截

proxy代理问题:

在vue3 cli 的配置下,配置了proxy代理:这样访问以/api的接口都会跳转到/localhost:3000/api下。

    proxy: {
      //拦截以api开始的请求,将/api 替换成http://localhost:3000, 浏览器同源策略,无法在前端 port:8080 访问后端 prot:3000 端口,需要借助代理拦截请求,进行接口转发
      "/api": {
        target: "http://localhost:3000"
      }
    }

但现在我有一个问题,我们之前说到文件静态资源通过http://localhost:3000/upload_f16d68210c6822f1000ce11f363f0815.jpg 来访问,这个路径按上述思路配置代理:会导致前端路由也一起访问后端接口,导致一锅粥,这样是不对的。

     "/": {
        target: "http://localhost:3000"
      },

最后只能采取死办法,引入koa-cors 实现后台跨域,并且通过绝对路径: url: "http://localhost:3000/"+ data.imgPath.imgBathPath,来访问。

总结:

本次完成毕设遇到的问题都是通过查看文档 + 百度查询的方式,当然这些方法在脑海里也有大致的印象,这次做一个总结。

到此这篇关于vue3+koa实现文件上传功能的文章就介绍到这了,更多相关vue3+koa文件上传功能内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • vue使用axios导出后台返回的文件流为excel表格详解

    vue使用axios导出后台返回的文件流为excel表格详解

    这篇文章主要介绍了vue使用axios导出后台返回的文件流为excel表格方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-08-08
  • Vue2 模板template的四种写法总结

    Vue2 模板template的四种写法总结

    下面小编就为大家分享一篇Vue2 模板template的四种写法总结,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-02-02
  • vue实现打地鼠小游戏

    vue实现打地鼠小游戏

    这篇文章主要为大家详细介绍了vue实现打地鼠小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-08-08
  • vue项目中使用html2canvas解决截图不全的问题

    vue项目中使用html2canvas解决截图不全的问题

    本文主要介绍了vue项目中使用html2canvas解决截图不全的问题
    2023-11-11
  • Vue+WebSocket页面实时刷新长连接的实现

    Vue+WebSocket页面实时刷新长连接的实现

    最近vue项目要做数据实时刷新,数据较大,会出现卡死情况,所以本文主要介绍了页面实时刷新长连接,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-06-06
  • 浅谈Vue2.0中v-for迭代语法的变化(key、index)

    浅谈Vue2.0中v-for迭代语法的变化(key、index)

    下面小编就为大家分享一篇浅谈Vue2.0中v-for迭代语法的变化(key、index),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-03-03
  • Vue中修改Mint UI的Toast默认样式之字体大小调整方式

    Vue中修改Mint UI的Toast默认样式之字体大小调整方式

    这篇文章主要介绍了Vue中修改Mint UI的Toast默认样式之字体大小调整方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-05-05
  • Vue router配置与使用分析讲解

    Vue router配置与使用分析讲解

    第一次写Vue项目,要用到router.js,看了一下官方文档,还是很懵逼,不知道怎么配置,又去看视频查资料,最后终于搞定了。话不多说,先上代码,我再讲一些要注意的细节
    2022-12-12
  • VUE使用draggable实现组件拖拽

    VUE使用draggable实现组件拖拽

    这篇文章主要为大家详细介绍了VUE使用draggable实现组件拖拽,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-04-04
  • 从0到1构建vueSSR项目之路由的构建

    从0到1构建vueSSR项目之路由的构建

    这篇文章主要介绍了从0到1构建vueSSR项目之路由的构建,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-03-03

最新评论