Using nodejs to develop its own map bed application

Time:2020-7-4

preface

In this paper, the author’s main replynodeJSThrough an online actual combat case to summarizenodeEcological common technology points and best practices. After that, it will take about a month to output 3 articles focusing on actual combatnodeJsProject, this article is the first one, mainly introduces how to usenodeJsDevelop a map bed application. This project is very practical for testing and personal service-oriented websites, and we can expand more powerful applications based on this. In this paper, the map bed project is mainly usedKoaIf you are not familiar with it, you can study it firstkoaOfficial website, or read the author wrote beforenodeJSThe article.

You will reap

  • The basic architecture of node application and the process of developing nodejs application
  • Koa + koa router + glob + node basic API usage
  • Introduction to the use of cross domain solution koa CORS, and how to cooperate with the front cross domain
  • Encapsulating file upload middleware based on @ koa / multer
  • Using react to develop front-end applications and basic use of Xui

text

First of all, the map bed application should ensure that our image resources can be accessed in different domains, and there is no cross domain problem. Moreover, it can support applications in different domains to upload pictures to the map bed, as shown in the following figure:
Using nodejs to develop its own map bed application
Combined with the above figure, we can do the application demand analysis first:
Using nodejs to develop its own map bed application
The above is a very simple map bed application requirements analysis, we will build the project architecture and develop our application based on this analysis. Before we start, let’s look at the simple implementation:

  • Access and upload images

Using nodejs to develop its own map bed application

  • Get picture link address

Using nodejs to develop its own map bed application

  • Delete picture

Using nodejs to develop its own map bed application
This display interface is just an example. We can design our own map bed management interface through the front-end way. The public API provided here can be called under any domain name, and there is no cross domain problem.

Front desk address: front desk of picture bed interface based on Xui

API open address: Map bed open address (free without black)

1. The basic architecture of node application and the process of developing nodejs application

About the project architecture of nodejs and how to organize nodejs directory, I will teach you how to build nodejs development environment and directory design in 30 minutes. This article has detailed instructions. After reading this article, you can learn to study it

Before developing any application, the first thing to do is to understand the requirements. After the requirements are clear, the technology selection can be made, and the development based onnodeJSThere are many technical solutions for the back-end application ofnodejsVery familiar, can use nativenodejsFor small and medium-sized applications, we can directly adoptKoaThe middleware mechanism and plug-in design concept can make it very convenient for us to develop our own middleware; if it involves more complex business lines, we can adopt itegg.jsperhapsnest.jsTo act asnodeJSBecause of the simple application of the chart bed in this paper, the author directly adopts it herekoaEcological development
Next, let’s take a look at the directory structure of our map bed application
Using nodejs to develop its own map bed application

2. Basic API usage of KOA + koa router + glob + node

Using nodejs to develop its own map bed application
The fastest way to learn koa is to directly read the official documents. Koa’s official documents are very simple and detailed, so you can check the official website if you don’t understand

1. Design of server routing (Interface)

We mainly use koa router for server-side routing, which is also very simple. The code is as follows:

const Koa = require('koa');
const Router = require('@koa/router');

const app = new Koa();
const router = new Router();
//Gets the routing interface of the list
router.get('/api/list', (ctx, next) => {
  //Logic of getting list
});
//Route interface for uploading pictures
router.post('/api/upload', (ctx, next) => {
  //Logic of uploading pictures
});

app
  .use(router.routes())
  .use(router.allowedMethods());

Because the application of map bed is very simple, we directly use the traditional way to implement it here. For the MVC architecture of nodejs, please refer to the article of node i wrote before

2. Use glob to obtain image paths in batch

Here, we mainly use the path to obtain images in batchglobThis method can be used when the amount of image data is small. However, once the image volume increases exponentially, it is more recommended to use the database to access. After all, IO operation is more expensive. The author here is to facilitate the use ofglobGlob is a third generation library based on node. It supports us to traverse the file directory in the way of pattern matching. The specific usage is as follows:

import glob from 'glob'
//Read file
router.get('/api/v0/files',
    ctx => {
        const files = glob.sync(`${staticPath}/uploads/*`)
        const result = files.map(item => {
            return `${config.staticPath}${item.split('public')[1]}`
        })
        
        ctx.body = {
            state: 200,
            result
        }
    }
);

In this way, the API for batch image acquisition is realized. Isn’t it very simple? We only need to access this interface to get the list of all pictures in the map bed. When we access this interface, the following data will be returned:
Using nodejs to develop its own map bed application

3. Introduction to the use of cross domain solution koa CORS, and how to cooperate with the front cross domain

Due to the same origin strategy of browser, any one of the protocol, domain name and port sending the request URL is regarded as cross domain if it is different from the current page address. There are many ways to achieve cross domain, such as jsonp cross domain, nginx reverse proxy, server-side modification header, and settings document.domain Post message technology is used, but the mainstream method is based on CORS

In order to provide services for different domains, we need to configure cross domain. Here we adopt the responsive cross domain solution provided by koa2 CORS. The principle is also very simple, that is, configure HTTP request response header information to enable our server to support different IP access

import cors from 'koa2-cors'
//Set up cross domain
app.use(cors({
    origin: function (ctx) {
        console.log(111, ctx.url)
        if (ctx.url.indexOf('/api/v0') > -1) {
            Return "*"; // allow requests from all domain names
        }
        return ' http://qutanqianduan.com '; // so that only http://qutanqianduan.com  This domain name request
    },
    Exposeheaders: ['www authenticate ','server authorization'], // get additional header information
    Maxage: 5, // this field is optional. It is used to specify the validity period of this pre check request. The unit is seconds
    credentials: true,
    Allowmethods: ['Get ','post','delete '], // request allowed methods
    Alloyheaders: ['content type ','authorization','accept ','x-requested-with'] // allowed header field names
}))

Through the above configuration, we can achieve basic cross domain. If we want to make only some specific interfaces cross domain, we can set the interface whitelist, or we can set the domain name whitelist to only let the specific domain name access our API interface. This situation is more suitable for the situation of cooperation and communication between multiple subsystems within the company

4. Encapsulate file upload middleware based on @ koa / multer

If the server wants to accept the files uploaded from the client, we also need to provide the file upload interface. Here, the author adopts the koa ecological mainstream implementation method @ koa / multer. The specific use of the official website is also very detailed, you can see the official website to learn @ koa / multer

1. Realize file upload interface

Next, we implement the file upload middleware based on it

import multer from '@koa/multer'
import { resolve } from 'path'
import fs from 'fs'

const rootImages = resolve(__dirname, '../../public/uploads')
//Upload file storage path, and file name
const storage = multer.diskStorage({
    destination: function (req, file, cb) {
        cb(null, rootImages)
    },
    filename: function (req, file, cb) {
        let [name, type] = file.originalname.split('.');
        cb(null, `${name}_${Date.now().toString(16)}.${type}`)
    }
})
//File upload restrictions
const limits = {
    Fields: 10, // number of non file fields
    File size: 1024 * 1024 * 2, // file size unit B
    Files: 1 // number of files
}

export const upload = multer({storage,limits})

From the above code, we set the target directory of file upload under the destination directory, and set the file name after uploading through the filename interface. Limits is the limitation of file operation, which can be configured according to your own needs

Secondly, the file upload interface is implemented with koa router

// lib/upload.js
//To catch multer errors
export const uploadSingleCatchError = async (ctx, next) => {
    let err = await upload.single('file')(ctx, next).then(res => res)
                .catch(err => err);
    if(err) {
        ctx.status = 500
        ctx.body = {
            state: 500,
            msg: err.message
        }
    }
}

// index.js
//Upload files
router.post('/api/v0/upload', uploadSingleCatchError,
    ctx => {
        let { filename, path, size } = ctx.file;
        let { source } = ctx.request.body || 'unknow';

        let url = `${config.staticPath}${path.split('/public')[1]}`
        
        ctx.body = {
            state: 200,
            filename,
            url,
            source,
            size
        }
    }
  );

In this way, we can upload pictures to our drawing bed through any client

2. Delete file interface

We use the native nodejs to implement the function of deleting files. Here we will use the FS module. The specific implementation is as follows:

// lib/upload.js
//Delete file
export const delFile = (path) => {
    return new Promise((resolve, reject) => {
        fs.unlink(path, (err) => {
            if(err) {
                reject(err)
            }else {
                resolve(null)
            }
        })
    }) 
}

//Delete file接口
  router.get('/api/v0/del',
    async ctx => {
        const { id } = ctx.query
        if(id) {
            const err = await delFile(`${staticPath}/uploads/${id}`)
            if(!err) {
                ctx.body = {
                    state: 200,
                    Result: 'deletion succeeded'
                }
            }else {
                ctx.code = 500
                ctx.body = {
                    state: 500,
                    Result: 'the file does not exist, deletion failed'
                }
            } 
        }else {
            ctx.code = 500
            ctx.body = {
                state: 500,
                Result: 'ID cannot be empty'
            }
        }  
    }
  )

In this way, we can click the delete button in our client application to delete the files on the map bed. Of course, there are many interface implementation details in this application, which will not be introduced one by one. Interested friends can study it

5. Using react to develop front-end applications and Xui basic use

The next step is to implement our map bed client. The implementation and design style of the client can be determined by ourselves. So here is just a brief introduction of the client implemented by the author. The author will use the react family bucket and the third-party UI library Xui, a lightweight UI component library based on react, to realize it. On how to develop a component library of my own, Can refer to the author’s previous article
First of all, we develop a simple interface of map bed application
Using nodejs to develop its own map bed application
Let’s first introduce the component library:

import React, { Component } from 'react'
import {  
  Notification,
  message,
  Layout, 
  Icon
} from '@alex_xu/xui'
const { Header, Content, Footer } = Layout

Then build our page:

class UploadPage extends Component {
    state = {
      fileList: []
    }

    componentDidMount() {
      fetch(apiUrl + '/files').then(res => res.json()).then(res => {
        this.setState({
          fileList: res.result
        })
      })
    }

    showAddress = (item) => {
      Notification.config({
        placement: 'topRight',
      })
      Notification.pop({
        type: 'success',
        Message: 'picture address',
        duration: 10,
        description: item
      })
    }

    render() {
      return (
        <div className="upload-wrap">
          <Layout>
            <Header fixed>
              <div className="logo"><Icon type="FaBattleNet" style={{fontSize: '30px', marginRight: '12px'}} />XOSS</div>
            </Header>
            <Content style={{marginTop: '48px', backgroundColor: '#f0f2f5'}}>
              {
                this.state.fileList.map((item, i) => {
                  return <div key={i} className="imgBox" onClick={this.showAddress.bind(this, item)}>
                    <img src={item}/>
                    <span className="del-btn" onClick={this.delFile.bind(this, item)}><Icon type="FaMinusCircle" style={{fontSize: '24px'}} /></span>
                  </div>
                })
              }
            </Content>
            < footer style = {{color: 'RGBA (0,0,0,. 5)'}} > interesting front end
          </Layout>
        </div>
      )
    }
}

export default UploadPage

For the HTTP library, we can use any mainstream library, such as Axios, UMI request, etc. this client code has been published to GitHub. You can run it locally on clone

Todooa management platform based on react + Redux + Redux thunk + Xui

last

Map bed complete code I will release in the interesting front end, if you want to learn moreH5 game, webpacknodegulpcss3javascriptnodeJSVisualization of canvas dataWelcome to study and discuss in “interesting front end” and explore the boundary of front end together.