ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

vue+element-ui +koa2 文件上传腾讯云踩坑记随笔

2019-07-16 22:01:57  阅读:433  来源: 互联网

标签:body 坑记 vue console log ctx element let file


首先,文件上传那些事儿,从头补一下https://cloud.tencent.com/developer/article/1004961

  • 第一个坑,koa-body的ctx.request获取

  一开始没有明确需求,以为需要先把文件写到后端,然后再上传腾讯云。所以研究了下koa-body怎么用文件流读写文件到后端。

  然后在获取ctx.request.body.files.file时怎么都获取不到

  感谢https://www.jianshu.com/p/34d0e1a5ac70

  严正提醒:

  新版本的koa-body通过ctx.request.files获取上传的文件  
  旧版本的koa-body通过ctx.request.body.files获取上传的文件

  • 第二个坑,表单上传前的图片宽高获取

  由于需要在后端请求一个需要当前图片宽高的接口,而formData中的file并虽然有name、size信息,但是并没有图片的宽高信息

  于是在前端获取宽高,并传送给后端。

    • tip1:表单提交前宽高获取

    这里我用的element-ui,前端代码如下

<template>
    <el-upload
            class="upload-demo"
            action="/api/uploadFile"
            :on-preview="handlePreview"
            :on-remove="handleRemove"
            :before-upload="getWidth"
            :file-list="fileList"
            list-type="picture"
            :data="pictureUpload"
    >
        <el-button size="small" type="primary">点击上传</el-button>
        <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
    </el-upload>
</template>

    使用fileReader()获取上传图片的宽高 https://www.haorooms.com/post/js_webapi_filereader

<script>
    export default {
        name: "upload",
        data(){
            return {
                pictureUpload: {
                    width: 0,
                    height: 0
                }
            }
        },
        methods: {
            handleRemove(file, fileList) {
                console.log(file, fileList);
            },
            handlePreview(file) {
                console.log(file);
            },
            getWidth(file) {
                // 获取文件尺寸
                let _this = this;
                return new Promise(function(resolve, reject) {

                    let reader = new FileReader()
                    reader.readAsDataURL(file)
                    reader.onload = function(theFile) {
                        let image = new Image()
                        image.src = theFile.target.result
                        image.onload = function() {
                            console.log(`${this.width}*${this.height}`)
                            console.log(this.width,this.height)
                            console.log(_this.fileList)
                            _this.pictureUpload.width = this.width;
                            _this.pictureUpload.height = this.height;
                            resolve(file);
                        }
                    }
                })
            }
        }

    }
</script>
    • tip2: 在后端如何接收Form Data里面的宽高呢?其实用ctx.request.body就可以取到了,和files不同

       

 后端的代码如下

var info = require('../config/info')
var Uploader = require('../modules/cos-uploader')
var JsonProxy = require('../modules/cos-uploader')
var fs = require("fs")
var path = require("path")
const crypto = require('crypto');

let jprxClient = new JsonProxy({env: 'beta'});
async function uploadFile (ctx, next) {
    let file = ctx.request.files.file;// 获取上传文件
    let userInfo = {
        "account": "122333221",
        "loginkey": "aaaaaaaaaaaaaaaaaa",
    }
    // 请求cosPath的参数
    let hash = crypto.createHash('sha1');
    let buffer = fs.readFileSync(file.path);
    hash.update(buffer);
    let sha1 = hash.digest('hex');
    let opts = {
        "authCtx": userInfo,
        "photoInfo": {
            "name": file.name,
            "size": file.size,
            "sha": sha1,
            "width": ctx.request.body.width,
            "height": ctx.request.body.height
        }
    };
    console.log('opts__________________',opts)
    let cosPath = '';
   // 接口请求省略
        // 上传腾讯云
        let localPath = file.path;
        let groupId = "temp";
        let remotePath = _getRemotePath(localPath, groupId);

        let uploader = new Uploader({
            // AppId: info.cos.AppId,
            SecretId: info.cos.SecretId,
            SecretKey: info.cos.SecretKey
        });
        let uploadOptions = {
            bucket: info.cos.Bucket+ '-' + info.cos.AppId,
            region: info.cos.Region,
            remotePath: remotePath,
            localPath: localPath
        };
        console.log('uploadOptions', uploadOptions);
        let uploadResult = await uploader.up(uploadOptions);
        console.log('upLoadResult____________________',uploadResult);
        if(uploadResult.statusCode == 200) {
            let opts = {
                "authCtx": userInfo,
                "sha": sha1
            };
            console.log('callBackOpts____________________________',opts)
            // 请求接口省略
            ctx.body = {
                location: uploadResult.Location,
                status: 0,
                message: 'success'
            }
        }else {
            ctx.body = {
                status: -1,
                message: uploadResult
            }
        }
}
// 可获取cosPath后不需要
function _getRemotePath(filePath, groupId) {
    var groupId = groupId || 'common_group_id';
    var hash = crypto.createHmac('sha256', 'useforalbums').update(fs.readFileSync(filePath)).digest('hex');
    return `albumgroup_${global._ENV === 'production' ? 'production' : 'beta'}/${groupId}/${hash}`;
}
module.exports = {
    uploadFile,
};

 

标签:body,坑记,vue,console,log,ctx,element,let,file
来源: https://www.cnblogs.com/xiaoyuchen/p/11197781.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有