zoukankan      html  css  js  c++  java
  • element-vue-koa2-mysql实现文件上传

    友情提示:这篇博客不会详细说明搭建过程

    阅读群体建议:第一次使用node或者koa2写文件上传或者下载,因为你不知道用fs的哪个方法,我也是从fs里试水试了一天,各种百度才搞出来的,特别学过java的来看更容易理解!希望可以帮助跟我一样自学的朋友!

    错误思路:我最开始想把文件上传到mysql中,字段换成blob就好了,但是我也不知道存没存进去,查出来是二进制也不会转换,搞死了,想着没有Tomcat服务器,怎么存储文件啊,后来发现,我们的项目本身就可以当做服务器,直接把文件存储到src下边就好了呀,没有必要非得存到Tomcat或者mysql里啦,这个错误思路,影响了我大半天,赶紧扭转思路,放下看吧!!!

    思路:

    保存:

      第一步:页面想后台传送文件流

      第二步:使用koa-router配合koa-body进行接收

      第三步:读取文件流let readStream = fs.createReadStream(file.path) 返回一个reader二进制文件 file为接收前台的文件

      第四步:将文件流写入本地,let writeStream = fs.createWriteStream(filePath) 

          注意:本机路径地址,我放到了koa2工程的/src/uploads/images/里边  所以引入const path = require("path") ,let filePath = path.resolve('src/uploads/images/'),会返回一个绝对路径,把这个绝对路径放到写入流的参数里

      第五步:readStream.pipe(writerStream) 这个必须要有,至于为什么,我目前还不清楚

      第六步:将这个filePaht绝对路径的地址保存到数据中,为了以后查询使用

    查询:

      第一步:从数据库中查询到文件的绝对路径 path

      第二步:查询该文件的流!使用let readStream = fs.readFileSync(path), 注意:这个方法是同步的,所以没有回调函数,只能定义一个变量接受返回值!最好不要用fs.readFile()这个方法,这个方法是异步的,会很麻烦

      第三步:如果是图片,将该文件转换成base64,let base64 = readStream.toString('base64')

          简写(第二步也可以简写成 let base64 = fs.readFileSync(path,'base64')

      第四步:转换成你想要的base64格式 比如:let base64 = "data:image/png;base64,"  + fs.readFileSync(path,'base64');

      第五步:ctx.body = base64; 就可以返回给前台了

    完毕  !!!!以上为简单的啰嗦的逻辑   !!!! 

    下边为代码,按照java的习惯,先从dao层开始写起来!!!!!!!

    第一步:mysql的配置,这个config.js我就不列出来,就算不列出来,想必你也懂得!

    import {
        DB
    } from '../config.js'
    
    async function mysql(opt1, opt2) {
    
        let mysql = require('mysql2/promise');
    
        let connection = await mysql.createConnection({
            host: DB.HOST,
            user: DB.USER,
            password: DB.PASSWORD,
            database: DB.DATABASE,
            port: DB.PROT
        });
    
        let [result, fields] = await connection.execute(opt1, opt2);
    
        await connection.end();
    
        return result
    }
    
    module.exports = mysql

    第二步:dao层,新增文件

    import {
        util,
        mysql,
        getsql,
    } from '../tool';
    
    class loginUser {
    // 新增图片
        async addPhoto(filePath){
            console.log('进入了dao层');
            let sql = 'insert into image (`image`) values ("'+ filePath + '+")';
            return await mysql(sql);
        }
    }
    module.exports = new loginUser();

    第三步:服务层,逻辑的处理,进行保存图片,导入第二不的dao层文件demo.js,这里服务层返回数据的格式不标准,不建议工作用,学习可以!

    import loginUser from '../../dao/demo.js';
    const fs = require('fs');
    const path = require('path');
    class login {
     }
        /**
         * 新增图片的方法
         * 
         * @param {any} ctx 
         * @memberof login
         */
        async addPhoto(ctx) {
            console.log('进入了服务层');
            let file = ctx.request.body.files.file;
            let filePath = path.join(path.resolve('src/uploads/images'), file.name);
            const reader = fs.createReadStream(file.path);
            const writer = fs.createWriteStream(filePath);
            reader.pipe(writer);
            let result;
            try {
                await loginUser.addPhoto(filePath).then(res => {
                    console.log(res);
                    result = res;
                })
                ctx.body = result;
            } catch (error) {
                console.log(error);
            }
        }
    }
    
    module.exports = new login();

    第四步:控制层,也叫路由层 ,调用了服务层demo.js中的addPhoto方法,这个里边啥都不用写,只需要对外暴露即可!

    import KoaRouter from 'koa-router'
    import service from '../service'
    const router = new KoaRouter({
        prefix: '/loginuser'
    })
    router.post('/addPhoto',demo.addPhoto);

    第五步:前段页面使用element-ui,把action写成路由对外暴露的路径即可,这里为loginuser/addPhoto

    <el-upload
          action="loginuser/addPhoto"
          list-type="picture-card"
          :on-preview="handlePictureCardPreview"
          :on-remove="handleRemove"
          :multiple="false">
          <i class="el-icon-plus"></i>
       </el-upload>

    以上为保存的逻辑!写的已经很详细了!!!

    下边是查询的,我就只列出服务层的代码,逻辑部分,否则有凑字数嫌疑,最重要的就是使用fs.readFileSync这个方法,还有如何拼凑base64,就这俩难点!

    // 查询图片服务
        async findImg(ctx) {
            console.log('进入图片查询服务层');
            let result = [];
            try {
                await loginUser.findImg().then(res => {
                    let index = 0;
                    for (let val of res) {
                        let read = fs.readFileSync(val.image,"base64");
                        let data = "data:image/jpeg;base64,"+read;
                        result.push(data);
                        index++;
                    }
                })
                console.log('开始执行ctx.body');
                console.log(result);
                ctx.body = result;
            } catch (error) {
    
            }
        }

    我把数据库的字段也列一下吧 

    没错,就一个字段,还是varchar类型我给了256个长度!

    最后:谢谢查看!!!!!!!

    连接:

    koa2接受文件:http://www.ruanyifeng.com/blog/2017/08/koa.html

    base64拼接:https://www.cnblogs.com/x-st/p/5220282.html 

    koa2官网demo:https://github.com/ruanyf/koa-demos/blob/master/demos/21.js

    欢迎一起探讨node的学习曲线,如何搭建好的koa2框架! 邮箱:zhou8337626@163.com

  • 相关阅读:
    4个方面教你怎么样成为一名及格的设计师
    CURL函数的GET和POST方式的两种写法(实现ajax跨域调用)
    微信公众平台接口配置问题
    wamp环境PHP安装mongodb扩展
    WAMP 403 Forbidden禁止访问
    PHP的CURL方法curl_setopt()函数案例介绍(抓取网页,POST数据)
    在微信中实现app软件中账号注册的功能实现
    form表单只提交数据而不进行页面跳转的解决方案
    背景图片适配手机屏幕大小的设置方法。。。。。。。。。。。。
    TP中二维数组的遍历输出
  • 原文地址:https://www.cnblogs.com/fooller/p/8284611.html
Copyright © 2011-2022 走看看