Koa2 From Beginner to Master (3)

Koa2-cors solves cross-domain problems

  • Reference documentation
  • The installationnpm install koa2-cors -S
  • use
var Koa = require('koa');
var cors = require('koa2-cors');
 
var app = new Koa();
app.use(cors({
  origin: function(ctx) {
    if (ctx.url === '/test') {
      return false;
    }
    return '*';
  },
  exposeHeaders: ['WWW-Authenticate', 'Server-Authorization'],
  maxAge: 5,
  credentials: true,
  allowMethods: ['GET', 'POST', 'DELETE'],
  allowHeaders: ['Content-Type', 'Authorization', 'Accept'],
}));
Copy the code

@koa-Multer handles photo uploads

The processing of picture files here is not completely encapsulated, but can be packaged according to your actual needs or situations. Here we explain in detail, single picture upload and multiple picture upload

  • multer

  • Important Blog References

  • Reference documentation

  • Blog reference

  • Install NPM install@koa /multer multer-s

  • Multipart /form-data data details

  • Use the single method for single file uploads and array or fields for multiple file uploads

  • Utils/imageupload.js defines the imageUpload operation in the utils folder, which is a utility file. It is not packaged as a function here. If necessary, it can be packaged according to personal needs

Note that the storage engine set the file path must exist, otherwise the error will be reported, here I created a new folder public/images to store images

// utils/ imageupload.js const multer = require('@koa/multer') const path = require('path') Const storage = multer.diskStorage({destination: function (req, file, cb) { cb(null, './public/images') }, filename: Function (req, file, cb) {let ran = math.floor (math.random ()*10000) Split ('.')[1] let fileName = '${date.now ()}${ran}.${ext}' cb(null, }}) const limits = {// fileSize: 250 * 1024, // fileSize: 250 * 1024, // fileSize: B, 1024 == 1.024 KB // files: Function checkFileType(file, Cb) {/ / allow the extension of the format const filetypes = / jpeg | JPG | PNG | GIF/const extname = filetypes.test(path.extname(file.originalname).toLowerCase()) const mimetype = filetypes.test(file.mimetype) if (mimeType && extName) {return cb(null, true)} else {// Upload file format error cb({message: 'file type error'})}} // Load configuration, when a series of restriction callbacks such as type checking and size limiting are performed, Const upload = multer({storage, fileFilter: function(req, file, cb) { checkFileType(file, cb) }, limits }) module.exports = uploadCopy the code

Single image file upload

  • Define the upload.js file in the route to handle the upload API and use the route in app.js
const users = require('./routes/users')
const uploads = require('./routes/upload')
app.use(users.routes(), users.allowedMethods())
app.use(uploads.routes(), uploads.allowedMethods())
Copy the code

const router = require('koa-router')() const upload = require('./.. /utils/imageUpload') const { SuccessModel, ErrorModel} = require('./.. /model/resModel') router.prefix('/upload') router.post('/image/single', async function (ctx, next) { let err = await upload.single('file')(ctx, Next).then(res=>res).catch(err=>err) // Error catch if (err) {ctx.body = new ErrorModel(err.message)} else {if (ctx.file == Undefined) {ctx.body = new ErrorModel(' ctx.body ')} else {ctx.body = new SuccessModel('success')}}}) module. Exports = undefined) {ctx.body = new SuccessModel('success')}}}) Module. Exports = undefined) {ctx.body = new SuccessModel('success')}}}) Module  routerCopy the code
  • Front-end usage

The file passed must be form data multipart/form-data

const formData = new FormData(); formData.append(‘file’, file)

Upload multiple picture files

  • Use the upload. Array ()

const router = require('koa-router')() const upload = require('./.. /utils/imageUpload') const { SuccessModel, ErrorModel} = require('./.. /model/resModel') router.prefix('/upload') router.post('/image/single', async function (ctx, next) { let err = await upload.single('file')(ctx, Next).then(res=>res).catch(err=>err) // Error catch if (err) {ctx.body = new ErrorModel(err.message)} else {if (ctx.file == Undefined) {ctx.body = new ErrorModel(' ctx.body ')} else {ctx.body = new SuccessModel('success')}}) Router. Post ('/image/multer', async (CTX, next) => {// upload.array(name, maxCount) name Let err = await upload.array('file', 6)(CTX, Next).then(res=>res).catch(err=>err) // Error catch if (err) {ctx.body = new ErrorModel(err.message)} else {if (ctx.files.length) {ctx.body = new SuccessModel('success')} else {ctx.body = new ErrorModel(' can't upload empty ')}}}) module.exports = routerCopy the code
  • Front-end usage

<template>
  <div>
    <input type="file" @change="change" ref="val" multiple>
  </div>
</template>

<script>
export default {
  name: 'Test',
  methods: {
    change() {
      var formData = new FormData()
      var len = this.$refs.val.files.length;
      for (var i = 0; i < len; i++) {
        formData.append('file', this.$refs.val.files[i])
      }
      this.$axios.post('http://localhost:3000/upload/image/multer', formData).then(res => {
        console.log(res)
      })
    }
  }
}
</script>

<style scoped>

</style>
Copy the code
  • There are other files that are not in image format among the selected files

  • All images in image format are selected, and the number of images does not exceed the limit

  • All images were selected, but the number of images exceeded the set limit of 6

Multiple pictures uploaded two

  • An upgraded version of upload.array() that can pass multiple fields

const router = require('koa-router')() const upload = require('./.. /utils/imageUpload') const { SuccessModel, ErrorModel} = require('./.. /model/resModel') router.prefix('/upload') router.post('/image/single', async function (ctx, next) { let err = await upload.single('file')(ctx, Next).then(res=>res).catch(err=>err) // Error catch if (err) {ctx.body = new ErrorModel(err.message)} else {ctx.body = new SuccessModel('success') } }) router.post('/image/multer', async (ctx, next) => { // upload.array(name, MaxCount) name indicates the name of the field when uploading. Let err = await upload.array('file', 6)(CTX, Next).then(res=>res).catch(err=>err) // Error catch if (err) {ctx.body = new ErrorModel(err.message)} else {ctx.body = new SuccessModel('success') } }) router.post('/image/multer-fields', async (ctx, next) => { // upload.fields([{name: '', maxCount: number}]) let err = await upload.fields([{ name: 'file1', maxCount: 1, }, { name: 'file2', maxCount: 2 } ])(ctx, Next).then(res=>res).catch(err=>err) if (err) {ctx.body = new ErrorModel(err.message)} else {// Ctx. files is an object containing {file1:[], file2: []} console.log(ctx.files) ctx.body = new SuccessModel('success') } }) module.exports = routerCopy the code
  • Front-end use, here is not tested, the field can not be transmitted

Uploading progress bar

  • Refer to the blog
  • The reference blog contains an introduction to various web requests XMLHttpRequest, jquery. ajax, axios
  • There is no need for the back end to do too much operation for the upload progress, just need to upload the file interface, for the upload progress is monitored by the front end
  • Use, the upload picture file here is relatively small, the upload speed is a little fast to see the effect, I manually adjust the network slow

<template> <div> <input type="file" ref="val" multiple> <div> <progress id="progress" :value="progress" Max = "100" > < / progress > < span > {{progress}} % < / span > < / div > < button @ click = "upload" > upload < / button > < / div > < / template > < script > export default { name: 'Test', data() { return { progress: 0 } }, methods: { upload() { let config = { headers: { 'Content-Type': 'multipart/form-data' }, onUploadProgress: E => {const {loaded, total} = e if (e.engthcomputable) {let progress = loaded/total * 100 // Progress = math.floor (progress) console.log(progress) this.progress = progress}}} var formData = new formData () formData.append('file', this.$refs.val.files[0]) console.log(formData.get('file')) this.$axios.post('http://localhost:3000/upload/image/single',  formData, config).then(res => { console.log(res) }) } } } </script> <style scoped> </style>Copy the code