前言
Express 是一个 Web 应用框架,可以帮助我们快速搭建一个 Web 应用
正文
1、Hello World
下面我们先来搭建一个简单的小型应用,熟悉 Express 的基本使用方法
- 首先创建一个新文件夹作为项目的根目录,然后在该文件夹下打开命令行
- 然后使用 npm init 命令生成一个 package.json 文件,它是项目的配置文件
- 接着使用 npm install --save express 命令安装 Express,它会放在 node_modules 目录下
- 最后创建 server.js 文件,并在该文件中编写如下代码:
// 引入 Express 模块 var express = require('express') // 创建 Express 实例 var app = express() // 设置路由 app.get('/', function (req, res) { res.send('Hello World') }) // 启动服务器,监听端口 5000 var server = app.listen(5000, '127.0.0.1', function() { console.log('server running at http://127.0.0.1:5000') })
上面就是一个简单的应用程序,我们现在暂时还不需要理解其中的语法,等下将会逐一进行讲解
最后打开命令行输入命令 node server.js
,打开 http://127.0.0.1:5000/ 即可看到 Hello World 问候语
2、基础路由设置
路由确定 应用程序如何响应特定的客户端请求
每个路由都可以有一个或多个处理函数,这些函数在路由匹配时执行,语法格式如下:
app.METHOD(PATH, HANDLER)
其中,METHOD 表示请求方法,PATH 表示匹配路径,HANDLER 表示路由匹配时的处理逻辑
以下面的代码为例,当客户端以 GET 方法请求根路径资源时,执行匿名函数,发送 Hello World 响应
app.get('/', function (req, res) { res.send('Hello World') })
(1)METHOD
METHOD 定义请求方法,Express 支持所有 HTTP 请求方法,下面是一些例子:
- app.get(PATH, HANDLER) 定义当使用 GET 方法请求 PATH 路径上的资源时执行逻辑 HANDLER
- app.post(PATH, HANDLER) 定义当使用 POST 方法请求 PATH 路径上的资源时执行逻辑 HANDLER
- app.all(PATH, HANDLER) 定义当使用任何方法请求 PATH 路径上的资源时执行逻辑 HANDLER
(2)PATH
PATH 定义匹配路径,它可以是字符串、字符串模式或正则表达式,下面是一些例子:
- '/about' 匹配请求路径 /about
- '/ab?cd' 匹配请求路径 /acd、/abcd(?:匹配 ? 前的字符 0 次或 1次)
- '/ab+cd' 匹配请求路径 /abcd,/abbcd 等等(+:匹配 + 前的字符 1 次或多次)
- /a/ 匹配任意包含字符 a 的请求路径(使用正则表达式几乎可以满足一切复杂的需求)
我们还可以在路径中 指定参数,参数以 :
为前缀,用于捕获指定位置的值,并将其保存在 req.params
var express = require('express') var app = express() app.get('/', function (req, res) { res.send('Hello World') }) app.get('/firstname/:firstname/lastname/:lastname', function (req, res) { let params = req.params let result = params.firstname + ' ' + params.lastname res.send(result) }) var server = app.listen(5000, '127.0.0.1', function() { console.log('server running at http://127.0.0.1:5000') }) /* * 执行结果: * 如果访问网址 http://127.0.0.1:5000 * 那么就会返回 Hello World * 如果访问网址 http://127.0.0.1:5000/firstname/Steve/lastname/Jobs * 那么就会返回 Steve Jobs **/
(3)HANDLER
HANDLER 是路由匹配时的处理逻辑,它可以是函数、函数数组或两者的组合形式
在使用多组函数时,必须确保使用 next()
方法将控制权传递给后续函数,否则将会直接终止
var express = require('express') var app = express() var sayHello = function (req, res) { res.send('Hello World') } var reverseMessage = function(req, res) { let message = req.params.message let reverse = message.split('').reverse().join('') res.send(reverse) } var showParams = function (req, res, next) { let params = req.params console.log('---Params') for (let prop in params) { console.log(prop + ': ' + params[prop]) } console.log('---------') next() } app.get('/', sayHello) app.get('/reverse/:message', [showParams, reverseMessage]) var server = app.listen(5000, '127.0.0.1', function() { console.log('server running at http://127.0.0.1:5000') })
一般情况下,函数带有两个参数,分别是 Request 和 Response 对象,用于处理请求和响应数据
Request 对象 常见的属性和方法有:
属性和方法 | 描述 |
ip | IP 地址 |
originalUrl | 原始 URL |
baseURL | 基础 URL |
protocol | 协议类型 |
hostname | 主机名 |
subdomains | 子域名 |
path | 资源路径 |
query | 查询字符串 |
route | 当前匹配路由 |
params | 路由参数,用于获取 GET 请求的内容 |
body | 当使用 body-parser 中间件时,包含请求主体,用于获取 POST 数据 |
cookies | 当使用 cookie-parser 中间件时,包含 Cookie 对象,用于获取 Cookie 内容 |
get(field) |
获取指定的 HTTP 请求头 |
Response 对象 常见的属性和方法有:
属性和方法 | 描述 |
set(field[,value]) |
设置 HTTP 响应头 |
get(field) |
返回 HTTP 响应头 |
append(field[,value]) |
添加 HTTP 响应头 |
cookie(name,value[,option]) |
设置 Cookie |
clearCookie(name[,options]) |
清除 Cookie |
redirect([status,]path) |
重定向到指定路径 |
send([body]) |
传送响应 |
sendStatus(code) |
传送状态码 |
sendFile(path[,options][,fn]) |
传送文件 |
json([body]) |
传送 JSON 数据 |
jsonp([body]) |
传送 JSONP 数据 |
end([data][,encoding]) |
结束响应 |
3、高级路由设置
(1)app.route()
如果需要为同一路径的不同请求方法定义不同的处理函数,app.route(path)
是一个不错的选择
app.route('/book') .get(function (req, res) { res.send('Get a book') }) .post(function (req, res) { res.send('Add a book') }) .put(function (req, res) { res.send('Update the book') })
(2)express.Router()
express.Router([options])
用于创建 Router 实例,它就像 express 实例一样,能添加路由和中间件
我们可以创建一个路由文件 router.js
,并在文件中编写如下代码:
var express = require('express') var router = express.Router() // 添加中间件 router.use((req, res, next) => { console.log('执行路由: ' + Date.now()) next() }) // 添加路由 router.get('/', (req, res, next) => { res.send('Home Page') }) router.get('/about', (req, res, next) => { res.send('About Page') }) module.exports = router
然后,我们可以在应用程序 server.js
中加载路由文件,代码如下:
var express = require('express') var router = require('./router') var app = express() app.use('/router', router) var server = app.listen(5000, '127.0.0.1', function() { console.log('server running at http://127.0.0.1:5000') })
4、中间件函数
中间件 (Middleware) 实际上是一个 函数,可以访问请求对象 Request,响应对象 Response 和 next 函数
中间件的加载顺序十分重要,先加载的中间件先执行,中间件可以分为以下几种类别
- 应用程序级中间件:通过
app.METHOD()
方法和app.use()
方法绑定到 express 实例
var express = require('express') var app = express() // 由于没有指定路径,所以每个请求都会执行该中间件函数 app.use(function (req, res, next) { // 中间件函数 console.log('Time: ' + Date.now()) next() }) app.get('/user/:id', function (req, res, next) { // 中间件函数 res.send('Hello, ' + req.params.id) }) var server = app.listen(5000, '127.0.0.1', function() { console.log('server running at http://127.0.0.1:5000') })
- 路由器级中间件:通过
router.METHOD()
方法和router.use()
方法绑定到 Router 实例
它与应用程序级中间件的工作方式相同
var express = require('express') var router = express.Router() router.use(function (req, res, next) { // 中间件函数 console.log('Time: ' + Date.now()) next() }) router.get('/user', function (req, res) { // 中间件函数 res.send('Hello, ' + req.params.id) }) var app = express() app.use('/virtual', router) var server = app.listen(5000, '127.0.0.1', function() { console.log('server running at http://127.0.0.1:5000') })
- 错误处理中间件:与应用程序级中间件和路由器级中间件的定义方式相同
区别在于错误处理中间件的参数有四个,分别是function(err, req, res, next)
app.use(function(err, req, res, next) { console.error(err.stack) res.status(500).send('Error!') })
- 内置中间件:常用的内置中间件是
express.static()
,将会在下面进行介绍 - 第三方中间件:常用的第三方中间件可以参考 官方文档
5、静态文件
Express 内置的中间件函数 express.static()
可以 挂载图片、CSS 和 JS 之类的静态文件,语法格式如下:
express.static(root, [options])
其中,root 表示储存静态文件的根目录路径,options 是一个对象,用于提供更详细的信息
我们创建一个项目,其中 public
目录用于储存静态文件,server.js
文件是程序主入口,目录结构如下:
+ app + node_module + public + images - icon.png - background.png - index.html - style.css - script.js - server.js - package.json
我们可以在 server.js
文件中声明 public
目录下的内容开放,如此客户端就可以通过地址直接请求资源
例如 http://127.0.0.1:5000/images/icon.png、http://127.0.0.1:5000/hello.html 等
app.use(express.static('public'))
如果需要创建 虚拟路径前缀,可以在挂载时指定,这样客户端需要在原有路径前添加虚拟前缀才可访问资源
例如 http://127.0.0.1:5000/static/images/icon.png、http://127.0.0.1:5000/static/hello.html 等
app.use('/static', express.static('public'))
文章知识点与官方知识档案匹配,可进一步学习相关知识