在
eggjs
中上传文件的官方文档
1、配置上传的路由
module.exports = (app) => {
const { router, controller } = app;
router.resources('file', '/api/v1/file', controller.file);
};
2、在config/config.default.js
中配置上传的基本配置(可以参考官方文档)
...
// 配置上传
config.multipart = {
fileSize: '50mb',
mode: 'stream',
fileExtensions: ['.xls', '.txt'], // 扩展几种上传的文件格式
};
...
3、安装几个基本的包
npm install await-stream-ready stream-wormhole dayjs
form
表单上传1、模板的代码
<form method="POST" action="/api/v1/file" enctype="multipart/form-data">
title: <input name="title" /> file: <input name="file" type="file" />
<button type="submit">Upload</button>
</form>
fs
及数据流写入文件(在控制器层)async create() {
// 获取文件流
const stream = await this.ctx.getFileStream();
// 定义文件名
const filename = Date.now() + path.extname(stream.filename).toLocaleLowerCase();
// 目标文件
const target = path.join('app/public/uploads', filename);
//
const writeStream = fs.createWriteStream(target);
console.log('-----------获取表单中其它数据 start--------------');
console.log(stream.fields);
console.log('-----------获取表单中其它数据 end--------------');
try {
//异步把文件流 写入
await awaitWriteStream(stream.pipe(writeStream));
} catch (err) {
//如果出现错误,关闭管道
await sendToWormhole(stream);
// 自定义方法
this.error(err);
}
// 自定义方法
this.success({ url: '/public/uploads/' + filename });
}
url
地址www.meimeitu8.com传递服务层,存到数据库中ajax
上传文件1、基本的html
页面
<h1>ajax提交</h1>
<input type="text" id="username" />
<input name="file" type="file" id="file" />
<button id="btn">提交</button>
2、jq
的ajax
<script>
$('#btn').on('click', function() {
console.log('提交按钮');
let formData = new FormData();
formData.append('title', $('#username').val());
formData.append('image', $('#file')[0].files[0]);
console.log(formData);
$.ajax({
url: '/api/v1/file',
data: formData,
method: 'post',
contentType: false,
processData: false,
success: function(result) {
console.log(result);
},
});
});
</script>
1、修改上传代码www.rsxedu.com的控制器
const fs = require('fs');
const path = require('path');
//故名思意 异步二进制 写入流
const awaitWriteStream = require('await-stream-ready').write;
//管道读入一个虫洞。
const sendToWormhole = require('stream-wormhole');
const dayjs = require('dayjs');
async create() {
const stream = await this.ctx.getFileStream();
console.log('-----------获取数据 start--------------');
console.log(stream.fields);
console.log('-----------获取数据 end--------------');
// 基础的目录
const uplaodBasePath = 'app/public/uploads';
// 生成文件名
const filename = `${Date.now()}${Number.parseInt(
Math.random() * 1000,
)}${path.extname(stream.filename).toLocaleLowerCase()}`;
// 生成文件夹
const dirname = dayjs(Date.now()).format('YYYY/MM/DD');
function mkdirsSync(dirname) {
if (fs.existsSync(dirname)) {
return true;
} else {
if (mkdirsSync(path.dirname(dirname))) {
fs.mkdirSync(dirname);
return true;
}
}
}
mkdirsSync(path.join(uplaodBasePath, dirname));
// 生成写入路径
const target = path.join(uplaodBasePath, dirname, filename);
// 写入流
const writeStream = fs.createWriteStream(target);
try {
//异步把文件流 写入
await awaitWriteStream(stream.pipe(writeStream));
} catch (err) {
//如果出现错误,关闭管道
await sendToWormhole(stream);
this.error();
}
this.success({ url: path.join('/public/uploads', dirname, filename) });
}
2、其它的都不变
3、上传生成的目录
2019
└── 06
└── 21
├── 1561097630832563.png
└── 1561097675536863.jpeg
1、在基类的控制器中
const { Controller } = require('egg');
const fs = require('fs');
const path = require('path');
//故名思意 异步二进制 写入流
const awaitWriteStream = require('await-stream-ready').write;
//管道读入一个虫洞。
const sendToWormhole = require('stream-wormhole');
const dayjs = require('dayjs');
class BaseController extends Controller {
// 上传文件的通用方法
async uploadFile(category = '') {
const stream = await this.ctx.getFileStream();
// 基础的目录
const uplaodBasePath = 'app/public/uploads';
// 生成文件名
const filename = `${Date.now()}${Number.parseInt(
Math.random() * 1000,
)}${path.extname(stream.filename).toLocaleLowerCase()}`;
// 生成文件夹
const dirname = dayjs(Date.now()).format('YYYY/MM/DD');
function mkdirsSync(dirname) {
if (fs.existsSync(dirname)) {
return true;
} else {
if (mkdirsSync(path.dirname(dirname))) {
fs.mkdirSync(dirname);
return true;
}
}
}
mkdirsSync(path.join(uplaodBasePath, category, dirname));
// 生成写入路径
const target = path.join(uplaodBasePath, category, dirname, filename);
// 写入流
const writeStream = fs.createWriteStream(target);
try {
//异步把文件流 写入
await awaitWriteStream(stream.pipe(writeStream));
} catch (err) {
//如果出现错误,关闭管道
await sendToWormhole(stream);
return {
error: '错误',
};
}
return {
url: path.join('/public/uploads', category, dirname, filename),
fields: stream.fields,
};
}
}
module.exports = BaseController;
2、在上传文件的控制器中使用
登录后复制const Controller = require('./../core/base_controller');
class FileController extends Controller {
async create() {
// 上传头像的,会在uploads文件夹下有个avatar的文件夹下面才是2019、06、21
const { url, fields } = await this.uploadFile('avatar');
const result = await 服务层;
this.success(url);
}
}