express framework Foundation

Installation and use

// Import express module
const express = require('express');
// Register express module
const app = express();
//Mount routing
app.get('/',(req,res)=>{
    res.send(`<h1>home page</h1>`);
})
app.get('/user',(req,res)=>{
    //req request object get request parameters
    res.send(req.query);
})
app.get('/user/:id',(req,res)=>{
    // req request object to get dynamic parameters
    res.send(req.params);
})
// Start server
app.listen(80,()=>{
    console.log("server running at http://127.0.0.1");
})

Managed static resources

//Managed static resources
//The path prefix is in the front, followed by static resources
app.use('/public',express.static('./clock'));

Route definition

// The route in Express consists of three parts: the type of request, the URL address of the request and the processing function. The format is as follows:
	app.METHOD(PATH,HANDLER)
// Type of METHOD request
// The URL address of the PATH request
// HANDLER function
	app.get('/user/,(req,res)=>{
		res.send(`This is routing`);
	});

Route matching mechanism

  1. Match according to the defined order
  2. The corresponding processing function will not be called until the request type and the requested URL match successfully at the same time

Modular routing

router.js custom routing module file

// Import express
const express = require('express');
// Start routing
const router = express.Router();
// Mount routing
router.get('/',(req,res)=>{
    res.send(`This is the home page`);
})
router.get('/user/list',(req,res)=>{
    res.send(`get user list`);
})
router.post('/user/add',(req,res)=>{
    res.send('post new add');
})
// Share out
module.exports = router;

server.js entry file

// 1.  Import express module
const express = require('express');
// 2. Start the express module
const app = express();
// 3. Import routing module
const router = require('./router');
// 4. Register routing
app.use('/api',router);
// 5. Start the server
app.listen(8080,()=>{
    console.log("server running at http://127.0.0.1:8080");
})

middleware

Middleware refers to the intermediate processing link of business process
Middleware generally needs to be registered before routing
After the middleware registers the routing error level

express middleware call process

express middleware format

Express middleware is essentially a function processing function. The format of express middleware is as follows:

app.get('/',(req,res,next)=>{
    next();	//The next function is the key to realize the continuous call of multiple middleware. It means to transfer the flow relationship to the next middleware or route.
})

Define a middleware function

const mw = function(req,res,next){
	console.log(`This is a middleware`);
	next();
}

Register global Middleware

// Import express module
const express = require('express');
// Instantiate express module
const app = express();
// First Middleware
const mw = (req,res,next)=>{
    req.a = 'a'
    console.log(`This is a middleware`);
    next();
}
// Second Middleware
const mw1 = (req,res,next)=>{
    req.a = 'a1'
    console.log(`Second Middleware`);
    next()
}
// The third Middleware
const mw2 = (req,res,next)=>{
    req.a = 'a2'
    console.log(`The third Middleware`);
    next()
}

// Register global Middleware 
app.use(mw);
app.use(mw1);
app.use(mw2);

// Mount routing
app.get('/',(req,res)=>{
    console.log(req.a);     //Multiple middleware share the same req request object and res response object
    res.send(`home page`);
})

// Turn on the server
app.listen(80,()=>{
    console.log("server running at http://127.0.0.1");
})

Register local Middleware

const express = require("express");

const app = express();

const mw1 = (req,res,next)=>{
    console.log('First Middleware');
    next();
}

const mw2 = (req,res,next)=>{
    console.log('Second Middleware');
    next();
}

// Register the first writing format of local Middleware
app.get('/',mw1,mw2,(req,res)=>{
    res.send("Home page.");
})

// Register the second writing format of local Middleware
app.post('/user',[mw1,mw2],(req,res)=>{
    res.send("User Page.");
})


app.listen(80,()=>{
    console.log("server running at http://127.0.0.1");
})

Middleware classification

  1. The middleware bound to the app instance is the application level middleware app Use ('middleware ');
  2. The middleware bound to the router instance is the routing level middleware router Use ("middleware");
  3. Error level middleware (register middleware after routing)
//Error level Middleware

const express = require('express');

const app = express();

const mw = (err,req,res,next)=>{
    res.send('Error:'+ err.message);
    next();
}

app.get('/api',(req,res)=>{
    // Customize an error and throw it
    throw new Error('Server error');
    res.send('api');
})

//The registration error level route needs to be registered after the route
app.use(mw);

app.listen(80,()=>{
    console.log("server running at http://127.0.0.1");
})
  1. express built-in Middleware
  1. express.static is a built-in middleware for quickly hosting static resources
  2. express.json parsing request body data in JSON format (compatible, only available in version 4.16.0 +)
  3. express.urlencoded parses the request body data in URL encoded format (compatible, only available in version 4.16.0 +)
const express = require('express');

const app = express();

// Register for express json () middleware, parsing json request body data
app.use(express.json());
// Register for express Urlencoded () middleware, parsing x-www-form-urlencoded request body data
app.use(express.urlencoded({extended:false}));

app.post('/json',(req,res)=>{
    // req. The body attribute can accept the request body data sent by the client. If it is not parsed, it defaults to underfined
    res.send(req.body);
})

app.post('/urlencoded',(req,res)=>{
    res.send(req.body);
})

app.listen(80,()=>{
    console.log("server running at http://127.0.0.1");
})
  1. Third party Middleware
const express = require('express');
// Import the third-party middleware body parser
const parser = require("body-parser");
const app = express();

// Middleware registration third party
app.use(parser.urlencoded({extended:false}));

app.post('/api/user',(req,res)=>{
    res.send(req.body);
})

app.listen(80,()=>{
    console.log("server running at http://127.0.0.1");
})

Custom parsing data middleware

Middleware content parse js

// Import nodejs built-in module querystring
const qs = require('querystring');


const mw = (req,res,next)=>{
    //Define a string
    let str = '';
    // Listen to the data event of the req object to get the data sent by the client to the server
    // The client will cut the data and send it to the server in batches. So the data event may be triggered multiple times,
    // Every time the data event is triggered, the data obtained is only a part of the complete data, and the received data needs to be spliced manually
    req.on('data',function(chunk){
        str += chunk
    });
    // Listen for the end event of req object. When the request body data is received, the end event of req will be triggered automatically
    req.on('end',function(){
        // Import querystring module and parse str data with parse method
        const body = qs.parse(str);
        // Mount the data in req On the body
        req.body = body;
        // Enter route
        next();
    })
}
// Share out
module.exports = mw;

Import file calling Middleware

const express = require('express');

const app = express();
// Import custom Middleware
const mw = require('./07.concent-parse');
// Registration Middleware
app.use(mw);
// Mount routing
app.post('/user',(req,res)=>{
    res.send(req.body);
})

app.listen(80,()=>{
    console.log("server running at http://127.0.0.1");
})
})

Custom API interface

apiRouter.js interface file

const express = require('express');
const router = express.Router();

router.get('/get',(req,res)=>{
    const query = req.query;
    res.send({
        status:1,
        msg:"GET request",
        data:query
    })
})

router.post('/post',(req,res)=>{
    const body = req.body;
    res.send({
        status:1,
        msg:"POST request",
        data:body
    })
})

module.exports = router;

app.js entry file

const express = require('express');

const app = express();

const apiRouter = require('./apiRouter');

app.use(express.urlencoded({extended:false}))
app.use(express.json())

app.use('/api',apiRouter);

app.listen(80,()=>{
    console.log("server running at http://127.0.0.1");
})

CORS cross domain resource sharing

Installing and using CORS Middleware

const cors = require('cors');
app.use(cors());

CORS definition

CORS (cross origin resource sharing) consists of a series of HTTP response headers, which determine whether the browser prevents the front-end JS code from obtaining resources across domains

CORS response header

  1. Access-Control-Allow-Origin
//If the value of access control allow origin field is specified as wildcard *, it means that requests from any domain are allowed. The example code is as follows:
res.setHeader('Access-Control-Allow-Origin','*');
//Specify the cross domain request from Baidu
res.setHeader('Access-Control-Allow-Origin','www.baidu.com');
  1. Access-Control-Allow-Headers

By default, CORS only supports the client to send the following 9 request headers to the server:
Accept, accept language, content language, DPR, Downlink, save data, viewport Width, Width, content type (values are limited to one of text/plain, multipart / form data, application/x-www-form-urlencoded)
If the client sends additional request header information to the server, you need to declare the additional request header on the server through access control allow headers, otherwise the request will fail!

//Allow the client to send additional content type request headers and X-Custom-Header request headers to the server
res.setHeader('Access-Control-Allow-Headers','Content-Type,X-Custom-Header');
  1. Access-Control-Allow-Methods

By default, CORS only supports GET, POST and HEAD requests initiated by clients.
If the client wants to request the resources of the server through PUT, DELETE, etc., it needs to indicate the HTTP method allowed by the actual request through access control alow methods on the server side.

//Only POST GET request methods are allowed
res.setHeader("Access-Control-Allow-Methods","GET,POST")
//Allow all request methods
res.setHeader("Access-Control-Allow-Methods","*")

Simple request and pre inspection request

  1. Simple request

1. Request method: one of GET, POST and HEAD
2. The HTTP header information shall not exceed the following fields: no custom header field, Accept, Accept language, content language, DPR, Downlink, save data, viewport Width, Width and content type (only three values: application/x-www-form-urlencoded, multipart / form data and text/plain)

  1. Pre inspection request

1. As long as the request meets any of the following conditions, a pre inspection request is required:
1.1 the request Method is the request Method type other than GET, POST and HEAD
1.2 the request header contains a custom header field
1.3 send data in application/json format to the server

Before the formal communication between the browser and the server, the browser will send an OPTION request for pre check to know whether the server allows the actual request. Therefore, this OPTION request is called "pre check request". After the server successfully responds to the pre inspection request, it will send the real request and carry the real data.

  1. difference

Characteristics of simple request: only one request will occur between the client and the server.
Characteristics of pre check request: two requests will occur between the client and the server. After the pre check request of OPTION is successful, the real request will be initiated.

mysql operation

const express =require('express');

const app = express();

const mysql = require('mysql');

const db = mysql.createPool({
    host:'127.0.0.1',
    user:'root',
    password:'',
    database:'mydb01'
})

//query data base
// const str = 'select * from users';
// db.query(str,(err,res)=>{
//     if(err) return console.log(err.message);
//     console.log(res);
// })

//Insert new data
// Placeholder?
// const str = 'insert into users (username,password) values(?,?)';
// const data = {username:'lwq',password:'123321'};
// db.query(str,[data.username,data.password],(err,res)=>{
//     if(err) return console.log('Insert failed ');
//     if(res.affectedRows===1){
//         console.log('Insert succeeded ');
//     }
// })
//Convenient way to insert data
// const sql = 'insert into users set ?';
// const data = {username:'lwq1',password:'admin321'};
// db.query(sql,data,(err,res)=>{
//     if(err) return console.log('Insert failed ');
//     if(res.affectedRows===1){
//         console.log('Insert succeeded ');
//     }
// })

//Convenient way to update data
const sql = 'update users set ? where id=?';
const data = {id:2,username:'zz',password:'000000'};
db.query(sql,[data,data.id],(err,res)=>{
    if(err) return console.log('Update failed');
    // Insert and update operations as long as the request is successful affectedrows =
    if(res.affectedRows === 1){
        console.log("Update successful");
    }
})

User authentication

session

There is no cross domain problem in the back-end interface of the request, and session authentication is used

// TODO_01: Please configure Session Middleware
const session = require('express-session');
app.use(session({
  secret:'hjc_is_good',//Arbitrary string
  resave:false,//Fixed writing
  saveUninitialized:true//Fixed writing
}))

// Login API interface
app.post('/api/login', (req, res) => {
  // Judge whether the login information submitted by the user is correct
  if (req.body.username !== 'admin' || req.body.password !== '000000') {
    return res.send({ status: 1, msg: 'Login failed' })
  }

  // TODO_02: please save the user information after successful login to the Session
  req.session.user = req.body;	//Mount the login information in session user
  req.session.islogin = true;	//Login status

  res.send({ status: 0, msg: 'Login successful' })
})

// Interface to get user name
app.get('/api/username', (req, res) => {
  // TODO_03: please get the user's name from the Session and respond to the client
  if(req.session.islogin !== true){
    return res.send({status:1,msg:"Unlisted account"});
  }
  // console.log(req.session);
  res.send({status:0,msg:'success',username:req.session.user.username});
})

// Exit the logged in interface
app.post('/api/logout', (req, res) => {
  // TODO_04: clear Session information
  req.session.destroy(); //Clear the session information saved by the server
  res.send({
    status:0,
    msg:'Exit successful'
  })
})

jwt

JWT (full English Name: JSON Web Token) is the most popular cross domain authentication solution at present
JWT usually consists of three parts: Header, Payload and Signature. English "." is used between the three separate
The Payload part is the real user information, which is the string generated after the user information is encrypted.
Header and Signature are security related parts, just to ensure the security of Token
The recommended approach is to put the HTTP request header in the JWT Authorization field

  1. Install JSON webtoken and express JWT Middleware
  2. Import the two modules and register the two middleware
  3. Configure an encrypted string screctStr
  4. Call the sign() method provided by the jsonwebtoken package to encrypt the user's information into a JWT string and respond to the client
  5. Every time the client accesses those authorized interfaces, it needs to actively send the Token string to the server through the Authorization field in the request header for identity authentication.
  6. The server can automatically restore the Token parsing sent by the client to JSON objects through express JWT, a middleware
  7. Use req The user parses the string information from the JWT object
  8. Capture the error generated after parsing JWT failed
  9. This error can be captured and processed through the error middleware of Express
//1. Import express JWT and JSON webtoken modules
const expressJWT = require('express-jwt');
const jwt = require('jsonwebtoken');

//2. Define secret key
const secretKey = 'hjcisgood';  //Arbitrary string

//3. Register parsing Middleware
//unless({path:[/^\/api\//]}) /api / this type of route does not need to be resolved
app.use(expressJWT({secret:secretKey,algorithms:['HS-256']}).unless({path:[/^\/api\//]}))

//4. Call jwt Sign() generates a jwt string and responds to the client
//Login interface
app.post('/api/login', function (req, res) {
  // Put req The data in the body request body is transferred to the userinfo constant
  const userinfo = req.body
  // Login failed
  if (userinfo.username !== 'admin' || userinfo.password !== '000000') {
    return res.send({
      status: 400,
      message: 'Login failed!'
    })
  }
  // {expiresIn:'60s'} set token expiration time
  tokenStr = jwe.sign({username:userinfo.username},secretKey,{expiresIn:'60s'});
  res.send({
  	status:0,
  	message:'Login successful',
  	token: tokenStr
  })
})


//5. This is an API interface with permission
app.get('/admin/getinfo', function (req, res) {
  // TODO_05: use req User gets the user information and sends the user information to the client using the data attribute
  res.send({
    status: 200,
    message: 'User information obtained successfully!',
    data: req.user // The user information to be sent to the client is jwt parsed and restored into a json object and saved in req In user
  })
})
//5.1 the front end can call this interface only when the authorization request header value is bear + < token >

//6. Registration error: the middleware captures the error caused by jwt parsing failure
app.use((err,req,res,next)=>{
	if(err.name==="UnauthorizedError"){
		res.send({status:401,message:"invalid token"});
	}
	res.send({status:500,message:"unknown error"});
})

nodemon tool

In the terminal, run the following command to install nodemon as a globally available tool:

Using nodemon

Keywords: node.js Middleware

Added by Az_Critter on Tue, 08 Feb 2022 01:13:16 +0200