koa+react进行图片上传

山水有轻音 2021-05-20 PM 214℃ 0条

一、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.jsctx.reqBooleanfalse
patchKoa将请求体打到 koa 的 ctx.requestBooleantrue
jsonLimitJSON 数据体的大小限制String / Integer1mb
formLimit限制表单请求体的大小String / Integer56kb
textLimit限制 text body 的大小String / Integer56kb
encoding表单的默认编码Stringutf-8
multipart是否支持 multipart-formdate 的表单Booleanfalse
urlencoded是否支持 urlencoded 的表单Booleantrue
text是否解析 text/plain 的表单Booleantrue
json是否解析 json 请求体Booleantrue
jsonStrict是否使用 json 严格模式,true 会只处理数组和对象Booleantrue
formidable配置更多的关于 multipart 的选项Object{}
onError错误处理Functionfunction(){}
stict严格模式,启用后不会解析 GET, HEAD, DELETEBooleantrue

2) formidable 的相关配置参数

参数名描述类型默认值
maxFields限制字段的数量Integer1000
maxFieldsSize限制字段的最大大小Integer2 * 1024 * 1024
uploadDir文件上传的文件夹Stringos.tmpDir()
keepExtensions保留原来的文件后缀Booleanfalse
hash如果要计算文件的 hash,则可以选择 md5/sha1Stringfalse
multipart是否支持多文件上传Booleantrue
onFileBegin文件上传前的一些设置操作Functionfunction(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);
          });
      }
    }
  };
标签: koa, koa-body

非特殊说明,本博所有文章均为博主原创。

评论啦~