EggJS+Antd文件上传排坑汇总

项目技术栈

前端:react+umi+antd
中间层:Eggjs
后端:Java

问题汇总

  1. 文件无法上传
  2. eggJs获取form-data请求的参数(带文件上传的请求)
  3. 使用file模式和stream模式的文件上传

1.文件无法上传

报错:

missing csrf token,request forgery跨站请求伪造

原因:
在这里插入图片描述
官网做的一种安全防控

解决方案有两种:

  1. 在bff的config中把csrf关闭

     config.multipart = {
          
          
        mode: 'file'
     };
    

    在这里插入图片描述

  2. 在前端项目中表单提交时,头部带上csrf-token

     headers: {
          
          
      	'x-csrf-token': getCookie("csrfToken")
     },
    

    在这里插入图片描述
    官网资料:安全威胁 CSRF 的防范

2.eggJs获取form-data请求的参数(带文件上传的请求)

分两种模式,获取参数的方式不一样

  1. file模式
    bff中config的设置为file
    在这里插入图片描述
    参数会在request.files
    在这里插入图片描述
  2. stream模式
    bff中config的设置为stream
    在这里插入图片描述
    ctx.getFileStream() 接口能获取到上传的文件流

在这里插入图片描述

3.使用file模式和stream模式的文件上传

  1. 使用file模式做文件上传(+前端需传入md5key参数)

    controller文件如下

    const {
          
           Controller } = require("egg");
    const FormStream = require("formstream");
    const cryptoMd5 = require("crypto");
    const fs = require("fs");
    const path = require("path");
    import {
          
           Method } from "../../config/type";
    
    class UploadController extends Controller {
          
          
      async createCourse() {
          
          
        const {
          
          
          ctx,
          config: {
          
           fileServer },
        } = this;
        const {
          
          
          query,
          request: {
          
           files, method },
        } = ctx;
        this.logger.info("current query: %j", query);
        const {
          
           filepath } = files[0];
    
        // 获取md5
        let fileData = fs.createReadStream(filepath);
        var fsHash = cryptoMd5.createHash("md5");
    
        fileData.on("data", function (d) {
          
          
          fsHash.update(d);
        });
    
        fileData.on("end", async function () {
          
          
          var md5 = fsHash.digest("base64");
          console.log("文件的MD5是:%s", md5);
          const form = new FormStream();
          // 设置普通的表单域
          form.field("md5Key", md5);
          // 上传文件
          form.file("file", path.resolve(filepath));
          const result = await ctx.curl(`${
            
            fileServer}/xx/addFileUrl`, {
          
          
            headers: form.headers(),
            stream: form,
            dataType: "json",
            method: method as Method,
          });
          ctx.body = result;
          console.log("---q--q-q--q-q----", result);
        });
      }
    }
    
    module.exports = UploadController;
    
    
  2. 使用stream模式做文件上传(单个)(+前端需传入md5key参数)

    controller文件如下

    const {
          
           Controller } = require("egg");
    const FormStream = require("formstream");
    const cryptoMd5 = require("crypto");
    const fs = require("fs");
    const path = require("path");
    import {
          
           Method } from "../../config/type";
    
    class UploadController extends Controller {
          
          
      async createCourse() {
          
          
        const {
          
          
          ctx,
          config: {
          
           fileServer },
        } = this;
        const {
          
          
          query,
          request: {
          
           method },
        } = ctx;
        this.logger.info("current query: %j", query);
    
        // 获取md5
         const ctx = this.ctx;
    	 const fileData= await ctx.getFileStream();
        var fsHash = cryptoMd5.createHash("md5");
    
        fileData.on("data", function (d) {
          
          
          fsHash.update(d);
        });
    
        fileData.on("end", async function () {
          
          
          var md5 = fsHash.digest("base64");
          console.log("文件的MD5是:%s", md5);
          const form = new FormStream();
          // 设置普通的表单域
          form.field("md5Key", md5);
          // 上传文件
          form.file("file", fileData);
          const result = await ctx.curl(`${
            
            fileServer}/xx/add-file`, {
          
          
            headers: form.headers(),
            stream: form,
            dataType: "json",
            method: method as Method,
          });
          ctx.body = result;
          console.log("---q--q-q--q-q----", result);
        });
      }
    }
    
    module.exports = UploadController;
    
    

猜你喜欢

转载自blog.csdn.net/qq_40593656/article/details/109165167