You need to install a few things to create, use, and test Express middleware. First you need Node and NPM. To make sure it's installed, run:
npm -v && node -v
You should see the installed versions of Node and NPM. If an error occurs, Node needs to be installed. All examples should be used under Node ver 8 and NPM ver 5.
This article uses Express version 4.x. This is important because there were significant changes from version 3.x to version 4.x.
First we use Express’s most basic built-in middleware. Create a new project and npm initialize it...
npm init npm install express --save Create server.js and paste the following code: const express = require('express'); const app = express(); app.get('/', (req, res, next) => { res.send('Welcome Home'); }); app.listen(3000);
Suppose you are running a web application using Node.js and Express on a web server. In this app, you need to log in for some pages.
When the web server receives a request for data, Express will provide you with a request object that contains information about the user and the data they requested. Express also gives you access to response objects, which can be modified before the web server responds to the user. These objects are usually shortened to req, res.
Middleware functions are an ideal place to modify the req and res objects with relevant information. For example after a user logs in, you can get their user details from the database and then store these details in res.user
.
async function userMiddleware (req, res, next) { try { const userData = await getUserData(req.params.id); //see app.get below if(userData) { req.user = userData; next(); } } catch(error) { res.status(500).send(error.message); //replace with proper error handling } }
Do not call this function if an error occurs and you do not want to execute other code. Remember to send a response in this case, otherwise the client will wait for a response until it times out.
var app = express(); //your normal route Handlers app.get('/user/:id', userMiddleware, userController);
You can chain middleware in a middleware array or by using multiple app.use
calls:
app.use(middlewareA); app.use(middlewareB); app.get('/', [middlewareC, middlewareD], handler);
Express After receiving the request, each middleware that matches the request will be run in the order of initialization until there is a termination operation.
So if an error occurs, all middlewares for handling errors will be called in sequence until one of them no longer calls next() until the function is called.
express.Router Use the express.Router class to create modular, installable routing processing. A routing instance is a complete middleware and routing system.
var router = express.Router() //Load router-level middleware by using the router.use() and router.METHOD() functions. //The following example creates a router as a module, loads a middleware function in it, // defines some routes, and mounts the router module on a path in the main app. var express = require(‘express’); var router = express.Router(); // a middleware function with no mount path. This code is executed for // every request to the router // logging async function logMiddleware (req, res, next) { try { console.log(req.user.id, new Date()); next(); } catch() { res.status(500).send(error.message); } } // authentication async function checkAuthentication(req, res, next) => { // check header or url parameters or post parameters for token const token = req.body.token || req.query.token || req.headers['x-access-token'] || req.headers['authorization']; if (token) { try { // verifies secret req.decoded = await jwt.verify(token, config.secret) let checkUser = await authenticateTokenHelper.getUserDetail(req); // if everything is good, save to request for use in other routes if (checkUser) { req.user = req.decoded next() } else { return res.status(403).json({ message: responseMessage.noAuthorized }) } } catch (err) { return res.status(401).json({ message: responseMessage.invalidToken }) } } else { // if there is no token return res.status(400).json({ message: responseMessage.invalidRequest }) } } router.use(logMiddleware); router.get('/user, checkAuthentication, handler);
Express has the following built-in middleware functions:
express.static
Provide static resources, such as HTML files, images, etc. express.json
Payload parses incoming requests in JSON. express.urlencoded
Parses incoming URL-encoded payload requests. Error handling middleware always takes four parameters (err, req, res, next) . You must identify it as an error-handling middleware function by providing four parameters. Even if you don't need to use the next object, you must specify it. Otherwise the next object will be interpreted as a regular middleware and errors will not be handled. The basic signature looks like this:
app.use(function (err, req, res, next) { console.error(err.stack) res.status(500).send('Something broke!') })
Example 1:
app.get('/users', (req, res, next) => { next(new Error('I am passing you an error!')); }); app.use((err, req, res, next) => { console.log(err); if(!res.headersSent){ res.status(500).send(err.message); } });
在这种情况下,管道末端的错误处理中间件将会处理该错误。你可能还会注意到,我检查了 res.headersSent
属性。这只是检查响应是否已经将标头发送到客户端。如果还没有,它将向客户端发送 HTTP 500 状态和错误消息。
例2:
你还可以链接错误处理中间件。通常以不同的方式处理不同类型的错误:
app.get('/users, (req, res, next) => { let err = new Error('I couldn\'t find it.'); err.httpStatusCode = 404; next(err); }); app.get('/user, (req, res, next) => { let err = new Error('I\'m sorry, you can\'t do that, Dave.'); err.httpStatusCode = 304; next(err); }); app.use((err, req, res, next) => { // handles not found errors if (err.httpStatusCode === 404) { res.status(400).render('NotFound'); } // handles unauthorized errors else if(err.httpStatusCode === 304){ res.status(304).render('Unauthorized'); } // catch all else if (!res.headersSent) { res.status(err.httpStatusCode || 500).render('UnknownError'); } next(err); });
在某些情况下,我们将向后端添加一些额外的功能。先安装 Node.js 模块获取所需的功能,然后在应用级别或路由器级别将其加载到你的应用中。
示例:当 body-parser 处理 Content-Type 请求标头时,所有中间件都将使用解析的正文填充 req.body
属性。
const express = require('express'); const bodyParser = require('body-parser'); const app = express(); app.use(bodyParser.urlencoded({extended:false})) app.use(bodyParser.json()) app.post('/save',(req,res)=>{ res.json({ "status":true, "payload":req.body }) } app.listen(3000,(req,res)=>{ console.log('server running on port') })
中间件功能是一种非常好的方式,可以对每个请求或针对特定路由的每个请求运行代码,并对请求或响应数据采取措施。中间件是现代 Web 服务器的重要组成部分,并且非常有用。
英文原文地址:https://www.thirdrocktechkno.com/blog/how-Node-JS-middleware-works/
为了保证的可读性,本文采用意译而非直译。
更多编程相关知识,请访问:编程入门!!
The above is the detailed content of A brief discussion on how Node.js middleware works. For more information, please follow other related articles on the PHP Chinese website!