egg.js 文件上传转发

原因

开发的项目是egg.js + redis + mysql + vue2.x 全家桶 全栈开发的项目,因为须要作文件上传,上传成功后还要给文件生成文件目录结构,而后还须要作压缩进行处理,而且文件太大,这样一来上传的速度确定会特别慢,处理起来也比较复杂。因而就偷个懒,丢给咱们后台去处理。由于 Python处理确定性能上要好不少(实际上是本身偷懒 ^_^)可是也要对接口作二次封装. 最初的想法是前端直接调后台,可是经理要求要封装一层,没办法,只能在node中调后台的接口,也就是 前端上传文件到node层 node接收文件再模拟Formdata 上传将文件发到 后台 python 中。因而就开始码代码,问题就所以产生 node怎么模拟表单上传?html

网上搜索半天,都是拼接参数,嗯,最怕的就是搞这么复杂的了,后来经过搜索npm插件,尼玛 找到了一款 form-data 插件,使用时候 后台死活也接收不到文件 后来想到了一款牛逼的插件 [superagent] [www.npmjs.com/package/sup…] www.jianshu.com/p/1432e0f29… 嗯,真香 什么请求代理 转发 通通搞定 用来作爬虫也足够强大,开始码代码,先来个node 前端就不写了,vue+axios + elementui 上传前端

eggjs 使用 eggjs 进行配置vue

config.multipart = { mode: "Stream", fileSize: "1024mb" };node

关于 stream的了解,能够百度,相关文章不少。python

'use strict';
 
const Service = require('egg').Service;
const path = require("path");
const request = require('superagent'); 
const sendToWormhole = require('stream-wormhole');
const fs = require('fs');
const toArray = require('stream-to-array');
class formService extends Service {
    async index() {
        const ctx = this.ctx;
        const url = 'http://xxxxx/eggpost/';
        const stream = await ctx.getFileStream();
        const target = path.join(this.config.baseDir, 'app/public', stream.filename);
        let result;
        try {
            const parts = await toArray(stream);
            let buf = Buffer.concat(parts);
            // 写入文件保存至本地
            fs.writeFileSync(target, buf);
            result = await request
                .post(url)
                .attach('file', target, stream.filename)
        } catch (err) {
            // 必须将上传的文件流消费掉,要否则浏览器响应会卡死
            await sendToWormhole(stream);
            throw err;
        }
        //在上传完毕后删除文件
        fs.unlink(target, function (err) {
            if (!err) {
                console.log('文件已删除:', target);
            }
        });
        return {
            result:result.text
        }
    }
}
 
module.exports = formService;
复制代码

Python 代码mysql

直接采用的 django 来实现,上代码ios

def eggpost(request):
    if request.method == 'GET':
        pass
    else:
        try:
            files = request.FILES.getlist('file')
            for f in files:
                destination = open(os.path.join(BASE_DIR, 'static', 'images', f.name), 'wb+')
                for chunk in f.chunks():
                    destination.write(chunk)
                destination.close()
 
            msg = {
                'status': 200,
                'msg': '上传成功',
            }
        except Exception as e:
            print(e)
            msg = {
                'status': 500,
                'msg': '上传失败',
            }
 
        return HttpResponse(json.dumps(msg,ensure_ascii=False))
复制代码

这样就上传成功了,很简单有木有? 其实也想过经过proxy代理中间件转发,可是又有问题,实现原理也是转发接口,element 里面会有延迟的问题,通过实践,最终采用这种方法。redis

代码看起来仍是挺简单的,可是对于有些人仍是有些帮住的,中间也踩了很多坑,最后也都是仍是解决了,有更好的实现方式 请指教~~sql

后来看到了有人也发了相关的转发思路,我只不过把本身的代码也贴出来,提供一种思路,不喜欢的请轻点喷哦npm

相关连接

相关文章
相关标签/搜索