项目技术栈
前端:react
+umi
+antd
中间层:Eggjs
后端:Java
问题汇总
- 文件无法上传
eggJs
获取form-data
请求的参数(带文件上传的请求)- 使用
file
模式和stream
模式的文件上传
1.文件无法上传
报错:
missing csrf token,request forgery跨站请求伪造
原因:
官网做的一种安全防控
解决方案有两种:
-
在bff的
config
中把csrf
关闭config.multipart = { mode: 'file' };
-
在前端项目中表单提交时,头部带上
csrf-token
headers: { 'x-csrf-token': getCookie("csrfToken") },
官网资料:安全威胁 CSRF 的防范
2.eggJs获取form-data请求的参数(带文件上传的请求)
分两种模式,获取参数的方式不一样
file
模式
bff中config
的设置为file
参数会在request.files
里
stream
模式
bff中config
的设置为stream
ctx.getFileStream()
接口能获取到上传的文件流
3.使用file
模式和stream
模式的文件上传
-
使用
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;
-
使用
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;