Express 是基于 Node.js 平台,快速、开放、极简的 web 开发框架
基本使用
安装
npm install express --save
示例代码
const express = require('express')
const app = express()
const port = 3000
app.get('/', (req, res) => {
res.send('Hello World!')
})
app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
})
Express 官方推荐脚手架
通过应用生成器工具 express-generator 可以快速创建一个应用的骨架。
你可以通过 npx (包含在 Node.js 8.2.0 及更高版本中)命令来运行 Express 应用程序生成器。
npx express-generator
命令行参数
-h, --help 输出使用方法
--version 输出版本号
-e, --ejs 添加对 ejs 模板引擎的支持
--hbs 添加对 handlebars 模板引擎的支持
--pug 添加对 pug 模板引擎的支持
-H, --hogan 添加对 hogan.js 模板引擎的支持
--no-view 创建不带视图引擎的项目
-v, --view <engine> 添加对视图引擎(view) <engine> 的支持 (ejs|hbs|hjs|jade|pug|twig|vash) (默认是 jade 模板引擎)
-c, --css <engine> 添加样式表引擎 <engine> 的支持 (less|stylus|compass|sass) (默认是普通的 css 文件)
--git 添加 .gitignore
-f, --force 强制在非空目录下创建
启动应用
DEBUG=myapp:* npm start
set DEBUG=myapp:* & npm start
$env:DEBUG='myapp:*'; npm start
然后在浏览器中打开 http://localhost:3000/ 网址就可以看到这个应用了。
如何利用 Express 托管静态文件
express.static 内置中间件函数可以为我们提供 图像、CSS 文件和 JavaScript 文件之类的静态文件托管
express.static(root, [options])
多个静态资源目录,请多次调用 express.static 中间件函数:
app.use(express.static('public'))
app.use(express.static('files'))
路由
路由指的是确定应用程序如何响应对特定端点的客户机请求,这是一个URI(或路径)和一个特定的HTTP请求方法(GET、POST等)。
每个路由都可以有一个或多个handler函数,这些函数在匹配路由时执行。
路由定义采用以下结构
app.METHOD(PATH, HANDLER)
/data/([\$])book
。app.get('/example/b', (req, res, next) => {
console.log('the response will be sent by the next function ...')
next()
}, (req, res) => {
res.send('Hello from B!')
})
app.route
app.route() 为路由路径创建可链接的路由处理程序。由于路径是在单个位置指定的,因此创建模块化路由很有帮助,还可以减少冗余和错别字。
下面是一个用app.route()定义的链式路由处理程序的例子。
app.route('/book')
.get((req, res) => {
res.send('Get a random book')
})
.post((req, res) => {
res.send('Add a book')
})
.put((req, res) => {
res.send('Update the book')
})
express.Router
express.Route 可以将路由器创建为一个模块,在其中加载一个中间件函数,定义一些路由,并将路由器模块挂载到主应用的某个路径上
const express = require('express')
const router = express.Router()
const app = express()
// middleware that is specific to this router
router.use((req, res, next) => {
console.log('Time: ', Date.now())
next()
})
// define the home page route
router.get('/', (req, res) => {
res.send('Birds home page')
})
// define the about route
router.get('/about', (req, res) => {
res.send('About birds')
})
app.use('/pub', router)
中间件
中间件是可以访问请求对象( req)、响应对象( res) 以及next应用程序请求-响应周期中的函数。该next函数是 Express 路由器中的一个函数,当被调用时,它会执行当前中间件之后的中间件。
如果当前的中间件函数没有结束请求,则必须调用next()将控制权传递给下一个中间件函数。否则,请求将被挂起。
中间件加载的顺序很重要:首先加载的中间件函数也首先执行
const express = require('express')
const app = express()
app.use((req, res, next) => {
console.log('Time:', Date.now())
next()
})
const express = require('express')
const app = express()
const router = express.Router()
// a middleware function with no mount path. This code is executed for every request to the router
router.use((req, res, next) => {
console.log('Time:', Date.now())
next()
})
app.use((err, req, res, next) => {
console.error(err.stack)
res.status(500).send('Something broke!')
})
内置中间件
如何覆盖 Express API
Express API 由请求和响应对象的各种方法和属性组成。这些都是通过原型继承的。Express API 有两个扩展点:
覆盖方法
app.response.sendStatus = function (statusCode, type, message) {
// code is intentionally kept simple for demonstration purpose
return this.contentType(type)
.status(statusCode)
.send(message)
}
覆盖属性
Object.defineProperty(app.request, 'ip', {
configurable: true,
enumerable: true,
get () { return this.get('Client-IP') }
})