做者:thirdrock team翻译:疯狂的技术宅javascript
原文:https://www.thirdrocktechkno....前端
未经容许严禁转载java
你须要安装一些东西来建立、使用和测试 Express 中间件。首先须要 Node 和 NPM。为确保已经安装,能够运行:node
npm -v && node -v
你应该看到已安装的 Node 和 NPM 版本。若是出现错误,则须要安装 Node。全部例子都应在 Node ver 8+ 和NPM ver 5+ 下使用。程序员
本文使用了 Express 4.x 版。这很重要,由于从 3.x 版到 4.x 版有重大的更改。web
首先咱们使用 Express 最基本的内置中间件。建立一个新项目并 npm 初始化它…面试
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);
假设你在 web 网络服务器上正在使用 Node.js 和 Express 运行Web应用程序。在此应用中,你须要登陆的某些页面。数据库
当 Web 服务器收到数据请求时,Express 将为你提供一个请求对象,其中包含有关用户及其所请求数据的信息。 Express 还使你能够访问响应对象,能够在Web服务器响应用户以前对其进行修改。这些对象一般缩短为 req,res。express
中间件函数是使用相关信息修改 req 和 res 对象的理想场所。例如用户登陆后,你能够从数据库中获取其用户详细信息,而后将这些详细信息存储在 res.user
中。npm
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 } }
若是出现错误,而且你不想执行其余代码,则不要调用该函数。请记住在这种状况下要发送响应,不然客户端将会等待响应直到超时。
var app = express(); //your normal route Handlers app.get('/user/:id', userMiddleware, userController);
你能够在中间件数组中或着经过使用多个 app.use
调用来连接中间件:
app.use(middlewareA); app.use(middlewareB); app.get('/', [middlewareC, middlewareD], handler);
Express 收到请求后,与请求相匹配的每一个中间件都将会按照初始化的顺序运行,直到有终止操做为止。
所以,若是发生错误,则将按顺序调用全部用于处理错误的中间件,直到其中一个再也不调用 next() 函数调用为止。
express.Router 使用 express.Router 类建立模块化的、可安装的路由处理。路由实例是一个完整的中间件和路由系统。
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 有如下内置的中间件功能:
express.static
提供静态资源,例如 HTML 文件,图像等。express.json
负载解析用 JSON 传入的请求。express.urlencoded
解析传入的用 URL 编码的有效载荷请求。错误处理中间件始终采用四个参数(err,req,res,next)。你必须经过提供四个参数来将其标识为错误处理中间件函数。即便你不须要使用 next 对象,也必须指定。不然 next 对象将被解释为常规中间件,并将会没法处理错误。基本签名以下所示:
app.use(function (err, req, res, next) { console.error(err.stack) res.status(500).send('Something broke!') })
例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 服务器的重要组成部分,而且很是有用。