文章目录
-
- 1.理解express
- 2.基本使用
- 3.路由
- 4.Express中间件
- 1. 调用流程:
- 2. 格式:
- 3. next 函数作用:
- 4. 定义中间件函数
- 5. 全局生效的中间件:
- 6. 中间件作用:
- 7. 局部生效的中间件:
- 8. 定义多个局部中间件,通过如下两种等价方式
- 9. 注意事项:
- 10. 中间件分类【按用法分】:
- 1. 应用级别 app.use; get; post
- 2. 路由级别 express.Router
- 3. 错误级别中间件:必须放到所有路由之后 4个参数
- 7. Express 内置 express.json(); express.urlencoded({ extended: false })
- 5. 第三方中间件 body-parser
- 5.Express写接口
- 1. 创建基本API 路由模块
- 2. 编写GET 接口
- 3. 编写POST接口
- 4 .编写接口 - 基于cors解决接口跨域问题
- 1.接口的跨域问题:
- 2.跨域——三个响应头(CORS:跨域资源共享)
- 1.CORS响应头部- Access-Control-Allow-Origin
- 2.CORS响应头部- Access-Control-Allow-Headers
- 3.CORS响应头部- Access-Control-Allow-Methods
- 3.跨域——请求的分类
-
- 3. 跨域——编写 jsonp 接口
0.学习目标:
◆能够使用express.static() 快速托管静态资源
◆能够使用express路由精简项目结构
◆能够使用常见的express中间件
◆能够使用express创建API接口
◆能够在express中启用cors跨域资源共享
1.理解express
- http 模块也可以创建Web 服务器,express是基于 http 内置模块【用起来复杂,开发效率低】进一步封装的,可以极大提高开发效率,快速方便创建 服务器【Web服务器 以及 API接口服务器】
- 基本使用:
- 获取URL中携带的查询参数
req.query
- 获取URL的动态参数
req.params
- 托管静态资源,创建静态资源服务器:
express.use(express.static('文件目录'))
,其中静态文件目录不会出现在URL中,托管多个,多次访问,
const express = require('express')
const app = express()
app.use(express.static('./clock'))
app.listen(80, () => {
console.log('express server running at local');
})
5. 挂载路径前缀: express.use('/文件路径',express.static('public'),访问的时候需要加前缀
2.基本使用
const express = require('express')
const app = express()
app.listen(80, () => {
console.log('express server running at local');
})
app.get('/user', (req, res) => {
res.send({ name: 'gyp', age: '20', gender: 'woman' })
})
app.post('/user', (req, res) => {
res.send('请求成功')
})
app.get('/', (req, res) => {
console.log(req.query);
res.send(req.query)
})
app.get('/user/ :ids/:name', (req, res) => {
console.log(req.params);
res.send(req.params)
})
3.路由
- 客户端请求与服务器处理函数之间的映射(一 一对应)关系,
- 组成:请求的类型,请求的URL地址,处理函数,
app.METHOD(PATH,HANDLER)
-
匹配过程:请求到达服务器,先经过路由经过先后顺序的匹配,请求类型以及请求URL地址同时匹配成功后,express将该请求转交给相应函数
-
为了方便对路由进行模块化的管理,Express不建议将路由直接挂载到app上,而是推荐将路由抽离为单独的模块。
5.app.use( ) 作用:注册全局中间件(static,router)
1. 向外托管静态函数
app.use(express.static('./clock'))
2. 注册路由模块
app.use(router)
- 挂载统一前缀 ,类似静态资源托管,在app.use内
4.Express中间件
1. 调用流程:
在服务器内,(可以连续调用多个中间件进行预处理)处理【请求】保证其达到标准(可以作为路由形式返回给客户端),一般包含输入和输出
2. 格式:
本质是function 处理函数, 与路由处理函数区别:中间件处理函数包含第三个形参是 next ,路由处理函数仅有req,res
3. next 函数作用:
多个中间件连续调用的关键,表示吧流转关系转交给下一个中间件或路由
4. 定义中间件函数
const express = require('express')
const mw = function(req, res, next) {
console.log('这是一个最简单的中间件函数');
next()
}
const app = express()
app.listen(80, () => {
console.log('80端口响应成功');
})
5. 全局生效的中间件:
客户端发起的任何请求,到达服务器之后,都会触发的中间件,叫做全局生效的中间价。通过调用app.use(中间件函数),即可定义一个全局生效的中间价
const mw = function(req, res, next) {
console.log('这是一个最简单的中间件函数');
next()
}
app.use(mw)
app.use(function(req, res, next) {
console.log('一个简单函数');
next()
})
6. 中间件作用:
多个中间件之间,共享一份 req和 res 。可以在上游的中间件统一为req和res添加自定义的属性和方法,供下游的中间件或路由使用
const express = require('express')
const app = express()
app.use(function(req, res, next) {
console.log('调用了第1个中间件');
next()
})
app.use(function(req, res, next) {
console.log('调用了第2个中间件');
next()
})
app.use('/user', function(req, res) {
res.send('Home page.')
})
app.listen(80, () => {
console.log('800端口启动');
})
7. 局部生效的中间件:
不使用app.use( ) 定义的中间件
const express = require('express')
const app = express()
const mw1 = function(req, res, next) {
console.log('我是中间件函数');
next()
}
app.use('/', mw1, function(req, res) {
res.send('Home page')
})
app.get('/user', function(req, res) {
res.send('Use page')
})
app.listen(80, () => {
console.log('局部生效的端口监听中');
})
8. 定义多个局部中间件,通过如下两种等价方式
const express = require('express')
const app = express()
const mw1 = (req, res, next) => {
console.log('调用了第一个局部生效的中间件')
next()
}
const mw2 = (req, res, next) => {
console.log('调用了第二个局部生效的中间件')
next()
}
app.get('/', [mw1, mw2], (req, res) => {
res.send('Home page.')
})
app.get('/user', (req, res) => {
res.send('User page.')
})
app.listen(80, function () {
console.log('Express server running at http://127.0.0.1')
})
9. 注意事项:
![1. 中间件只能在路由之前注册
2. 客户端发送过来的请求可以连续调用多个中间件处理
3. 执行完中间件的业务代码后,不要忘记调用next( )函数
4.](https://img-blog.csdnimg.cn/2d19016e6f9d49a1bad011ea71b22f97.png)
10. 中间件分类【按用法分】:
1. 应用级别 app.use; get; post
2. 路由级别 express.Router
3. 错误级别中间件:必须放到所有路由之后 4个参数
7. Express 内置 express.json(); express.urlencoded({ extended: false })
app.use(express.json())
app.use(express.urlencoded({ extended: false }))
const express = require('express')
const app = express()
app.use(express.json())
app.use(express.urlencoded({ extended: false }))
app.use('/user', (req, res) => {
console.log(req.body);
res.send('ok')
})
app.post('/book', (req, res) => {
console.log(req.body);
res.send('oook')
})
app.listen(80, () => {
console.log('80端口监听中');
})
5. 第三方中间件 body-parser
const parser = require('body-parser')
app.use(parser.urlencoded({ extended: false }))
const express = require('express')
const app = express()
app.use(express.json())
app.use(express.urlencoded({ extended: false }))
app.post('/user', (req, res) => {
console.log(req.body)
res.send('ok')
})
app.post('/book', (req, res) => {
console.log(req.body)
res.send('ok')
})
app.listen(80, function () {
console.log('Express server running at http://127.0.0.1')
})
- 自定义中间件
自己手动模拟一个类似于express.urlencoded这样的中间件,来解析POST提交到服务器的表单数据。
实现步骤:
①定义中间件
app.use((req, res, next) => {
})
②监听req的data事件
③监听req的end事件
④使用querystring模块解析请求体数据
const express = require('express')
const app = express()
const qs = require('querystring')
app.use('/user', (req, res) => {
let str = ''
req.on('data', (chunk) => {
str += chunk
})
req.on('end', () => {
const body = qs.parse(str)
console.log(body);
})
res.send('ok')
})
app.listen(80, () => {
console.log('在监听啦!');
})
⑤将解析出来的数据对象挂载为req.body
const express = require('express')
const app = express()
const qs = require('querystring')
app.use((req, res, next) => {
let str = ''
req.on('data', (chunk) => {
str += chunk
})
req.on('end', () => {
const body = qs.parse(str)
req.body = body
next()
})
})
app.post('/user', (req, res) => {
res.send(req.body)
})
app.listen(80, function () {
console.log('Express server running at http://127.0.0.1')
})
⑥将自定义中间件封装为模块
封装函数
const qs = require('querystring')
const bodyParser = (req, res, next) => {
let str = ''
req.on('data', (chunk) => {
str += chunk
})
req.on('end', () => {
const body = qs.parse(str)
req.body = body
next()
}
}
module.exports = bodyParser
调用函数
const customBodyParser = require('./49.4.custom-body-parser')
app.use(customBodyParser)
app.post('/user', (req, res) => {
res.send(req.body)
})
5.Express写接口
(以下代码均省略创建基本服务器:导入模块,创建服务器以及【需要实现的路由部分】设置监听端口)
1. 创建基本API 路由模块
2. 编写GET 接口
const express = require('express')
const router = express.Router()
router.get('/get', (req, res) => {
const query = req.query
res.send({
status: 0,
msg: 'GET请求成功!',
data: query
})
})
module.exports = router
调用GET接口
const express = require('express')
const app = express()
const router = require('./49.5.apiRouter')
app.use('/api', router)
app.listen(80, () => {
console.log('80端口监听成功');
})
3. 编写POST接口
router.post('/post', (req, res) => {
const body = req.body
res.send({
status: 0,
msg: 'POST 请求成功!',
data: body
})
})
4 .编写接口 - 基于cors解决接口跨域问题
1.接口的跨域问题:
刚才编写的GET和POST请求,存在一个很严重的问题:不支持跨域请求。
解决接口跨域问题的方案主要有两种:
1.CORS(主流的方案,推荐使用)
2.JSONP(有缺陷的解决方案:只支持GET请求,很少使用)
使用cors中间件解决跨域问题
const cors = require('cors')
app.use(cors())
2.跨域——三个响应头(CORS:跨域资源共享)
1.CORS响应头部- Access-Control-Allow-Origin
2.CORS响应头部- Access-Control-Allow-Headers
3.CORS响应头部- Access-Control-Allow-Methods
3.跨域——请求的分类
1. 简单请求
2.预检请求
谷歌浏览器无法演示预检请求,建议用火狐
两者区别
3. 跨域——编写 jsonp 接口
- 概念: 概念:浏览器端通过
app.get('/api/jsonp', (req, res) => {
const funcName = req.query.callback
const data = { name: 'GYP', age: 20 }
const scriptStr = '${funcName}(${JSON.stringify(data)})'
res.send(scriptStr)
})
const cors = require('cors')
app.use(cors())
.在网页中使用jQuery发起JSONP请求
$('#btnJSONP').on('click', function() {
$.ajax({
type: 'GET',
url: 'http://127.0.0.1/api/jsonp',
dataType: 'jsonp',
success: function(res) {
console.log(res);
}
})
})
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)