Skip to content

Commit 605863a

Browse files
author
公众号:Rong姐姐好可爱
authored
Merge pull request #110 from lir0115/feat/exprss-apis
2 parents 33370c6 + b5615bd commit 605863a

18 files changed

+1014
-0
lines changed
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
# Express框架的API演示Demo
2+
3+
`express`模块提供了很多API方法,要了解、使用这些API去解决一些实际问题,首先需要安装:
4+
5+
```bash
6+
## 安装express
7+
npm install express --save
8+
```
9+
10+
Express框架主要提供了`express对象``application对象``request对象``response对象``router对象`的API方法,往往在使用Express框架时,
11+
项目入口文件的第一行就是对框架的引用,例如:
12+
13+
```js
14+
// 引入express模块
15+
const express=require('express')
16+
```
17+
18+
因为,这些API方法都来源`express`模块,针对不用的应用场景做的一些封装
19+
20+
## express()方法
21+
22+
express模块的入口其实是到处一个函数,通常是像上面引入一样,用变量`express`来接受,查看源码:
23+
24+
![express入口函数](./images/express-init.png)
25+
26+
可以看出引入的`express`模块,实质是导出一个`createApplication`方法,用来创建`express`的应用实例,这也说明为什么往往在引入`express`后,
27+
第二行代码就是创建`application`对象实例
28+
29+
```js
30+
// 导入模块
31+
const express = require('express')
32+
// 创建express应用对象
33+
const app = express()
34+
```
35+
36+
设置可以从源码中看到,这个`application`对象上还绑定了`request``response`两个对象,使用`Object.create`创建的、分别处理请求和响应。
37+
38+
除了提供创建app实例的方法,在源码导出时,还在express模块上挂载一些中间件,查看源码:
39+
40+
![](./images/express-middleware.png)
41+
42+
> 这里也许会有疑惑,导出的一个函数,使用express变量去接收时,创建出app实例对象,为什么在函数上又能去挂载一些中间件呢?
43+
> 其实在js发展早期,很多概念都是利用函数、对象、原型链去实现的,导出的函数可以理解为构造函数,挂载的中间件实质上也是一些方法、对象,
44+
> 可以理解为使用static关键字标记的静态方法。
45+
46+
总之,如果将这里导出的express理解为一个``,将createApplication方法理解为构造函数,将中间件理解为静态方法,应该就要好理解很多。
47+
48+
> js也是到ES6推出后才有了类的概念,并且也是利用函数+对象来实现的。
49+
50+
这里的理解,我在阅读源码的时候发现,结合Java的面向对象思想获取更好理解,接下来就说说express类上面挂载的静态方法、中间件
51+
52+
### 数据处理
53+
54+
Express框架内置中间件
55+
56+
- `express.json()`
57+
- `express.raw()`
58+
- `express.text()`
59+
- `express.urlencoded()`
60+
61+
都是基于`body-parser`模块,实质上就是利用`body-parser`中的`json()``raw()``text()``urlencoded()`方法,查看源码:
62+
63+
![](./images/body-parse-interface.png)
64+
65+
具体用法可以参考模块:[body-parser](https://www.npmjs.com/package/body-parser)
66+
67+
**可以对客户端请求传递的数据做处理,前置中间件处理好数据,交给下游的中间件、处理函数来实现逻辑**
68+
69+
数据处理中间件的一些参数含义:
70+
71+
@[code js](@code/express/apps/apis-demo/express.js)
72+
73+
这里要重点提一下JSON.parse()的用法,例如:
74+
75+
```js
76+
JSON.parse("{}"); // {}
77+
JSON.parse("true"); // true
78+
JSON.parse('"foo"'); // "foo"
79+
JSON.parse('[1, 5, "false"]'); // [1, 5, "false"]
80+
JSON.parse("null"); // null
81+
82+
JSON.parse(
83+
'{"p": 5}',
84+
(key, value) =>
85+
typeof value === "number"
86+
? value * 2 // return value * 2 for numbers
87+
: value, // return everything else unchanged
88+
);
89+
// { p: 10 }
90+
```
91+
92+
参考:[JSON.parse() API用法](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#Example.3A_Using_the_reviver_parameter)
93+
94+
### 静态资源
95+
96+
Express中内置的中间件功能。提供静态文件托管管理,基于`serve-static`
97+
98+
模块用法参考:[serve-static](https://www.npmjs.com/package/serve-static)
99+
100+
`express.static()`的基础用法:
101+
102+
@[code js](@code/express/apps/static-source-demo/app.js)
103+
104+
基于Express框架,关于静态文件托管,单独开了一篇做介绍,传送门:[静态资源托管](./静态文件.md)
105+
106+
### 路由
107+
108+
提供`express.Router()`创建一个新的路由器对象,约定接口的请求路径,例如:
109+
110+
@[code js](@code/express/apps/apis-demo/express-router.js)
111+
112+
express.Router()创建路由器对象时也支持一些额外的参数,查看源码:
113+
114+
![](./images/express-router-options.png)
115+
116+
其中:
117+
118+
- `caseSensitive`:配置是否对路由地址大小写敏感,布尔类型。默认false,即:大小写不敏感,`/test``/Test`效果一样。
119+
- `mergeParams`:保留req.params父路由器的值,布尔类型。如果父级和子级的参数名称有冲突,则子级的值优先。默认false
120+
- `strict`:是否开始严格模式路由,布尔类型。默认false,即:`/test``/test/`效果一样
121+
122+
路由器的用途还有很多,不仅支持多种请求类型的接口定义,还能分层管理,后面将单独开一篇详细讲讲,传送门:[路由的使用](./路由的使用.md)
123+
124+
## application对象
125+
126+
## request对象
127+
128+
## response对象
129+
130+
## router对象
131+
132+
## 参考
133+
134+
- <https://www.npmjs.com/package/express>
135+
- <https://expressjs.com/en/4x/api.html>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
const express = require('express')
2+
const router = express.Router()
3+
4+
// 当前路由配置中间件
5+
router.use(async(req, res, next) => {
6+
console.log('打印req对象', req)
7+
console.log('打印res对象', res)
8+
// 只有执行next()函数,请求才会继续向下走处理逻辑
9+
await next()
10+
})
11+
12+
// 设置该路由管理的路径
13+
router.get('/get-request', async(req, res, next) => {
14+
console.log('完成接口的一些业务逻辑')
15+
16+
res.json({
17+
code: 200,
18+
message: '响应成功'
19+
})
20+
})
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
const express = require('express')
2+
const app = express()
3+
4+
express.raw({
5+
// 可选参数,布尔类型
6+
// 是否禁用压缩的请求体数据,默认为true,false时拒绝请求数据
7+
inflate: undefined,
8+
// 可选参数,数字或字符
9+
// 限制请求体的大小,默认100kb
10+
limit: undefined,
11+
// 可选参数,字符或字符数组
12+
// 约定什么类型的数据会被该中间件处理,默认值:"application/octet-stream"
13+
type: [],
14+
// 可选参数,函数包含req、res、buffer、encoding四个参数
15+
// 提供原始的请求正文Buffer数据、编码等信息,可以通过抛错来终止解析
16+
verify(req, res, buf, encoding) {
17+
}
18+
})
19+
20+
express.json({
21+
// ... 除raw函数包含的参数外,还额外包含
22+
23+
// 可选参数,布尔类型
24+
// 设置是否使用严格模式,默认为true,只接收对象和数组
25+
// 设置false时,接收一切可以JSON.parse()处理的数据
26+
strict: true,
27+
// 可选参数,函数类型
28+
// 设置的这个函数,将直接放在JSON.parse()的第二个参数中使用
29+
// 参考JSON.parse()的API:
30+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#Example.3A_Using_the_reviver_parameter
31+
reviver(key, value) {
32+
}
33+
})
34+
35+
express.text({
36+
// ... 除raw函数包含的参数外,还额外包含
37+
38+
// 可选参数,字符串
39+
// 如果请求的header中没有指定Content-Type类型,指定文本内容的编码类型, 默认utf-8
40+
defaultCharset: undefined
41+
})
42+
43+
express.urlencoded({
44+
// ... 除raw函数包含的参数外,还额外包含
45+
46+
// 可选参数,布尔类型
47+
// 运行定制模块类解析URL地址中的参数
48+
// false时,使用querystring模块解析
49+
// true时,使用qs模块解析
50+
extended: undefined,
51+
// 可选参数,数字类型
52+
// 允许URL地址中传递的参数最大字段个数,默认为1000
53+
// 当参数个数超出时,返回客户端 413 状态码,表示请求体过大
54+
parameterLimit: undefined
55+
})
56+
57+
80.7 KB
Loading
101 KB
Loading
44.2 KB
Loading
34.6 KB
Loading

0 commit comments

Comments
 (0)