一、koa后端操作
1、安装koa-body
npm install koa-body --save
然后进行koa-body的配置
由于之前有安装使用
koa-bodyparser
,其实koa-body就包含koa-bodyparser的解析部分,也无需安装koa-multer
,如果koa-bodyparser不注释掉,前端调用其他请求接口就会出现server error BadRequestError: request aborted
错误,原因就是这个两个中间件冲突引起的
app.js配置如下
const Koa = require('koa')
const app = new Koa()
const views = require('koa-views')
const json = require('koa-json')
const onerror = require('koa-onerror')
const bodyparser = require('koa-bodyparser')
const serve = require("koa-static");
const logger = require('koa-logger')
const cors = require("koa2-cors");
const koaBody = require("koa-body");
const index = require('./routes/index')
const users = require('./routes/users')
const publics = require("./routes/publics");
const path = require("path");
// error handler
onerror(app)
// 1.静态资源服务,指定对外提供访问的根目录
app.use(serve(path.join(__dirname, '/public')));
// middlewares
/* app.use(bodyparser({ --注释掉这个中间键
enableTypes:['json', 'form', 'text']
})) */
app.use(
koaBody({
enableTypes: ["json", "form", "text"],
multipart: true,
strict: false,
formidable: {
maxFileSize: 5 * 1024 * 1024, // 设置上传文件大小最大限制,默认5M
uploadDir: path.join(__dirname, "public/upload/"), //设置文件上传的目录
keepExtensions: true, // 保留文件扩展名
},
})
);
app.use(json())
app.use(logger())
app.use(require('koa-static')(__dirname + '/public'))
app.use(views(__dirname + '/views', {
extension: 'pug'
}))
// logger
app.use(async (ctx, next) => {
const start = new Date()
await next()
const ms = new Date() - start
console.log(`${ctx.method} ${ctx.url} - ${ms}ms`)
})
//允许跨域
app.use(cors())
// routes
app.use(index.routes(), index.allowedMethods())
app.use(users.routes(), users.allowedMethods())
app.use(publics.routes(), publics.allowedMethods())
// error-handling
app.on('error', (err, ctx) => {
console.error('server error', err, ctx)
});
module.exports = app
2、koa后端上传接口
const path = require("path"); // 图片路径
class PublicControler {
static async uplod(ctx) {
const file = ctx.request.files.file
const basename = path.basename(file.path)
const size = (file.size/1024)/1024 --图片尺寸大小
try{
ctx.response.status = 200;
if(size>5){
ctx.body = {
code: 201,
message: "图片上传超过5M",
};
}else{
ctx.body = {
code: 200,
data: {
path: file.path, --返回本地文件路径
url: `${ctx.origin}/public/upload/${basename}`,--返回域名文件路径 ctx.origin(当前域名)
},
message: "图片上传成功",
};
}
}catch(error){
ctx.response.status = 500;
ctx.body = {
code: 500,
message: "上传错误"
};
}
}
}
module.exports = PublicControler;
因为默认开启多个文件上传,因此 ctx.request.files 是一个对象,
而且是通过表单的 name=photo 属性作为对象的 key,值便是一个 File 对象,有用的字段如下:
参数名 | 描述 |
---|---|
size | 文件大小 |
path | 文件上传的目录 |
name | 文件原始名称 |
type | 文件类型 |
lastModifiedDate | 上次更新时间 |
3、关于koa-body的配置
1) koa-body
的基本参数
参数名 | 描述 | 类型 | 默认值 |
---|---|---|---|
patchNode | 将请求体打到原生 node.js 的ctx.req 中 | Boolean | false |
patchKoa | 将请求体打到 koa 的 ctx.request 中 | Boolean | true |
jsonLimit | JSON 数据体的大小限制 | String / Integer | 1mb |
formLimit | 限制表单请求体的大小 | String / Integer | 56kb |
textLimit | 限制 text body 的大小 | String / Integer | 56kb |
encoding | 表单的默认编码 | String | utf-8 |
multipart | 是否支持 multipart-formdate 的表单 | Boolean | false |
urlencoded | 是否支持 urlencoded 的表单 | Boolean | true |
text | 是否解析 text/plain 的表单 | Boolean | true |
json | 是否解析 json 请求体 | Boolean | true |
jsonStrict | 是否使用 json 严格模式,true 会只处理数组和对象 | Boolean | true |
formidable | 配置更多的关于 multipart 的选项 | Object | {} |
onError | 错误处理 | Function | function(){} |
stict | 严格模式,启用后不会解析 GET, HEAD, DELETE | Boolean | true |
2) formidable
的相关配置参数
参数名 | 描述 | 类型 | 默认值 |
---|---|---|---|
maxFields | 限制字段的数量 | Integer | 1000 |
maxFieldsSize | 限制字段的最大大小 | Integer | 2 * 1024 * 1024 |
uploadDir | 文件上传的文件夹 | String | os.tmpDir() |
keepExtensions | 保留原来的文件后缀 | Boolean | false |
hash | 如果要计算文件的 hash ,则可以选择 md5/sha1 | String | false |
multipart | 是否支持多文件上传 | Boolean | true |
onFileBegin | 文件上传前的一些设置操作 | Function | function(name,file){} |
二、react前端调用
<Upload
name="file"
action={`${this.api.login.uplod}`} --上传的地址
beforeUpload={this.beforeUpload}
className="uplod"
showUploadList={false} --不显示列表
>
<Button icon="upload">上传图片</Button>
</Upload>
接口调用
beforeUpload = (e) => {
const size = (e.size/1024)/1024
if (e.type != "image/png" && e.type != "image/jpeg"&&e.type!="image/jpg") {
message.warning("格式不对");
return false;
}else{
const formData = new FormData(); --用表单形式上传
formData.append("file", e);
if(size>5){
message.warning('图片上传超过5M,请重新上传');
}else{
this.post(`${this.api.login.uplod}`, formData)
.then((res) => {
if (res.code == 200) {
message.success(res.message);
this.setState({
imgUrl: res.data.path,
});
} else {
message.warning(res.message);
}
})
.catch((res) => {
message.warning(res.message);
});
}
}
};