一、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); }); } } };