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

相關連接

相關文章
相關標籤/搜索