egg+react实现图片上传
react
render里的标签
//render里的
<input
style={{ width: '0' }}
id="file"
onChange={this.selectImg}
name="imgs"
type="file"
/>//input
{this.mapImgs()}//上传的图片可视化的列表
//添加图片的按钮
<div onClick={this.inpClick}>添加图片</div>
this.state里的数据
在这里插入代码片
点击实现的方法
//点击事件
inpClick = (e) => {
e.stopPropagation()
var inp = document.getElementById('file')
inp.click()
}
//遍历图片的方法
mapImgs = () => {
let { imgs } = this.state
// console.log(imgs, 111)
return imgs.map((item, index) => {
return (
<div className="imgs_div" key={index}>
<img src={item} />//记得给图片加宽高
<i onClick={() => this.delImg(index)}>×</i>
</div>
)
})
}
//删除图片的方法
delImg = (index) => {
let { imgs } = this.state
imgs.splice(index, 1)
this.setState({
imgs,
})
}
//获取图片文件的
selectImg = (e) => {
let { imgs } = this.state
let file = e.target.files[0]
let _that = this
var fileReader = new FileReader()
fileReader.readAsDataURL(file)
fileReader.onload = function () {
var data = fileReader.result.split(',')[1]
// atob方法用于解码使用 base-64 编码的字符串。
data = window.atob(data)
// Uint8Array 数组类型表示一个8位无符号整型数组,创建时内容被初始化为0。创建完后,可以以对象的方式或使用数组下标索引的方式引用数组中的元素。
var ia = new Uint8Array(data.length)
for (var i = 0; i < data.length; i++) {
ia[i] = data.charCodeAt(i)
}
// Blob() 构造函数返回一个新的 Blob 对象。 blob的内容由参数数组中给出的值的串联组成。
let img = new Blob([ia], { type: 'image/png' })
var fmData = new FormData()
fmData.append('avatar', img, 'avatar.png')
Unit.postApi2('http://localhost:7001/api/upload', fmData).then((res) => {
if (res.data.code == 200) {
console.log(res.data.data.avatar)
imgs.push(res.data.data.avatar)
_that.setState({
imgs,
})
}
})
}
}
egg
config下的config.default.js
/* eslint valid-jsdoc: "off" */
"use strict";
/**
* @param {Egg.EggAppInfo} appInfo app info
*/
module.exports = (appInfo) => {
/**
* built-in config
* @type {Egg.EggAppConfig}
**/
const config = (exports = {});
*
// 图片上传
config.uploadDir = "app/public/upload";
// add your middleware config here
config.middleware = [];
config.uploadDir = "app/public/upload";
config.mysql = {
clients: {
// clientId, 获取client实例,需要通过 app.mysql.get('clientId') 获取
db1: {
// host
host: "localhost",
// 端口号
port: "3306",
// 用户名
user: "root",
// 密码
password: "****",
// 数据库名
database: "****",
},
// ...
},
// 所有数据库配置的默认值
default: {},
// 是否加载到 app 上,默认开启
app: true,
// 是否加载到 agent 上,默认关闭
agent: false,
};
// post 请求 403 invalid csrf token
config.security = {
csrf: {
enable: false,
},
domainWhiteList: ["*"],
};
config.cors = {
origin: "*", // 匹配规则 域名+端口 *则为全匹配
allowMethods: "GET,HEAD,PUT,POST,DELETE,PATCH",
};
config.uploadDir = "app/public/upload";
// add your user config here
const userConfig = {
// myAppName: 'egg',
};
return {
...config,
...userConfig,
};
};
service新建一个upload.js
'use strict';
const Service = require('egg').Service;
const path = require("path");
const sd = require('silly-datetime');
const mkdirp = require('mkdirp');
class ToolsService extends Service {
/**
* 获取文件上传目录
* @param {*} filename
*/
async getUploadFile(filename) {
// 1.获取当前日期
let day = sd.format(new Date(), 'YYYYMMDD');
// 2.创建图片保存的路径
let dir = path.join(this.config.uploadDir, day);
await mkdirp(dir); // 不存在就创建目录
let date = Date.now(); // 毫秒数
// 返回图片保存的路径
let uploadDir = path.join(dir, date + '_' + filename);
// let uploadDir = path.join(dir, date + path.extname(filename));
// app\public\upload\20200312\1536895331666.png
return {
uploadDir,
saveDir: this.ctx.origin + uploadDir.slice(3).replace(/\\/g, '/')
}
}
}
module.exports = ToolsService;
controller新建一个upload.js
'use strict';
const Controller = require('egg').Controller;
const fs = require("fs");
const pump = require("pump");
class HomeController extends Controller {
async savePicture() {
const { ctx } = this;
const parts = ctx.multipart({ autoFields: true });
let files = {};
let stream;
while ((stream = await parts()) != null) {
if (!stream.filename) {
break;
}
const fieldname = stream.fieldname; // file表单的名字
// 上传图片的目录
const dir = await this.service.tool.getUploadFile(stream.filename);
const target = dir.uploadDir;
const writeStream = fs.createWriteStream(target);
await pump(stream, writeStream);
files = Object.assign(files, {
[fieldname]: dir.saveDir
});
}
if (Object.keys(files).length > 0) {
ctx.body = {
code: 200,
message: '图片上传成功',
data: files
}
} else {
ctx.body = {
code: 500,
message: '图片上传失败',
data: {}
}
}
}
}
module.exports = HomeController;
router.js添加路由
// 上传图片
router.post("/api/upload", controller.upload.savePicture);