express的使用
注意: Express 是一个第三方模块,用于快速搭建服务器(替代http模块) Express 是一个基于 Node.js 平台,快速、开放、极简的web 开发框架。
1.express中 GET 请求 中的 req.query 是用来获取客户端发送请求时携带的查询字符串
app.get('/',(req,res)=>{ // 注意: 在express中 req.query可以访问到用户发送过来的查询参数 console.log(req.query) res.send(req.query) })
-
1 express中 GET 请求 中的 req.params 是用来动态匹配URL携带的参数
app.get('/gyj/:id',(req,res)=>{ // 注意: :id 是动态参数 // req.params 是动态匹配的url参数 console.log(req.params) res.send(req.params) })
2.使用express.static()提供的托管静态资源,可以非常方便的创建一个静态资源服务器 对外使用
2.1 使用方法 :
app.use(express.static('需要对外开放文件的路径'))
3.挂载路径前缀
3.1.使用 方法
app.use('/gyj',express.static('需要对外开放文件的路径'))
4.安装 nodemon (可以监听代码发生改变时 ,自动刷新 不需要手动关闭终端 在重新打开了)
4.1 在终端输入命令
npm i -g nodemon
4.2 使用方法 :
nodemon app.js
5. 路由的匹配过程
5.1 路由就是客户端发送过得请求 ,与服务器处理函数之间的映射关系5.2 只有 请求URL和请求的方式同时匹配才会执行对应的函数
6.创建自定义路由模板
// 导入express 模块 const express = require('express') // 调用express中的 Router方法 创建路由对象 const router = express.Router() // 挂载具体的路由 router.get('/gyj/haoshuai', (req, res) => { res.send('发起了GET请求成功') }) router.post('/gyj/haoshuai', (req, res) => { res.send('发起了POST请求成功') }) // 向外导出路由对象 module.exports = router
6.1 导入自定义路由模板 并使用
// 导入 express 模块 const express = require('express') // 创建web 服务器 const app = express() // 导入自定义路由模块 const router = require('./03-router') // 注意 : app.use()方法 就是用来注册全局中间件 // 使用app.use()注册路由模块 app.use(router) // 启动服务器 app.listen(80, () => { console.log('http://127.0.0.1') })
6.2 挂载路由前缀
// 使用app.use()注册路由模块时,并添加统一的访问前缀 /api app.use('/api',router)
7.Express 中间件,本质就是一个 function 处理函数
注意 : 在function处理函数中 如果存在 next 形参 那么它就是中间件处理函数 , 而路由处理函数只包括 req res 这两种形参
7.1 代码示例:
app.get('/',(req,res,next)=>{ console.log('发起了GET请求') })
8.next()函数的作用
注意 : next()函数 是实现多个中间件连续调用的关键,它表示把流传关系转交给下一个中间件或者路由
9.定义一个最简单的中间件函数
const express = require('express') const app = express() // 定义一个简单的中间件函数 const mw = function(req,res,next) { console.log('这是一个最简单的中间件函数') // 把流传关系转交给下一个中间件或者路由 next() } app.listen(80,()=> { console.log('http://127.0.0.1') })
10.将 mw 中间件函数定义为全局生效的中间件
注意 : app.use()是将中间件函数定义为全局生效的方法
// 生效一个全局中间件 app.use(mw)
11.定义全局生效的中间件的简化形式
注意:: app.use(function(req,res,next) {} ) 这个中间件函数是不会筛选请求地址和请求方式
app.use( function(req,res,next ){ console.log('这是最简单的中间件函数) //必须调用 next() 才能流传到下一个中间件或者路由 next() })
12.中间件的作用
注意:多个中间件之间,共享同一份req和res,基于这样的特性,我们可以在上游的中间件中,统一为req或res对象添加自定义的属性或方法,供下游的中间件或路由进行使用
12.1 代码示例:
const express = require('express') const app = express() // 生成一个最简化的 全局中间件函数 app.use(function(req,res,next){ // 定义一个时间属性 const time = Date.now() // 给req添加 time 属性 req.starDate = time next() }) app.get('/',(req,res)=>{ res.send('发起了GET请求'+req.starDate) }) app.listen(80,()=> { console.log('http://127.0.0.1') })
13.定义多个中间件
注意 : 全局中间件 默认是不认任何路径和请求方式的 使用全局中间件必须调用next()这个中间件函数 否则无法执行下面的代码
注意: 中间件的执行过程是从上往下一次执行,但是执行前 首先会看是否满足中间件条件(满足条件有: 请求路径. 请求方式 . 但是默认全局中间件是不看这些条件的 ,是直接可以进行该全局中间件执行里面的代码) , 满足才会进行该中间件执行里面的代码 如果不满足则会向下一次寻找满足条件的中间件 . 每个中间件必须有next()才会寻找下一个满足条件的中间件,然后执行该中间件里的代码
const express = require('express') const app = express() // 生成一个全局中间件 app.use(function(req,res,next){ console.log('我是第一个中间件') // 调用中间件函数 执行下一个中间件 next() }) app.use(function(req,res,next){ console.log('我是第二个中间件') next() }) app.use(function(req,res,next){ console.log('我是第三个中间件') next() }) // 生成一个路由局部中间件 app.get('/a',(req,res)=>{ res.send('say hello') }) app.listen(80,()=>{ console.log('http://127.0.0.1') })
14.生成局部中间件
const express = require('express') const app = express() // 注意 : 只有使用 app.use()才能生效全局有效的中间件 // 单纯定义一个中间件函数,并没有使用,给谁添加 就在当前中间件生效 const mw = function(req,res,next) { console.log('我是局部中间件') // 必须调用next() 否则不会执行下一个中间件或路由 next() } // 给这个路由添加局部中间件 mw app.get('/a',mw,function(req,res){ res.send('Say Hello') }) app.get('/',function(req,res){ res.send('Say two') }) app.listen(80,()=>{ console.log('http://127.0.0.1') })
15.生成多个局部中间件
const express = require('express') const app = express() // 定义中间件函数 const mw1 = function(req,res,next) { console.log('我是第一个中间件函数') next() } const mw2 = function (req,res,next) { console.log('我是第二个中间件函数') next() } app.get('/a',mw1,mw2,(req,res)=>{ res.send('Say Hello!!!') }) app.get('/abc',(req,res)=>{ res.send('Say gyj !!!') }) app.listen(80,()=>{ console.log('http://127.0.0.1') })
16.使用中间件注意的5个事项
1.必须在路由之前注册中间件(路由指的是: app.get(function(req,res){}))
2.客户端发送过来的请求可以调用多个中间件进行处理
3.执行完中间件业务代码后,记得要添加 next() 函数
4.为了防止代码逻辑混乱,不要在调用了 next() 函数 后 在额外书写代码
5.连续调用多个中间件时,多个中间件之间的 req, res 对象 是共享的
17.演示错误中间件
作用 : 捕获服务器发生的错误,防止页面崩溃
注意 : 错误中间件必须写在路由之后
const express = require('express') const app = express() // 生成一个路由 app.get('/a', (req, res) => { // 扔出一个错误 throw new Error('服务器内部发生了一个错误') //此时不会执行下面的代码 res.send('Say Hello') }) // 生成一个 全局错误级别中间件 app.use((err, req, res, next) => { console.log('发生了错误' + err.message) // 向客户端发错错误消息 res.send('Error'+ err.message) }) app.listen(80, () => { console.log('http://127.0.0.1') })
18.演示内置中间件
const express = require('express') const app = express() // 配置内置中间件 调用express.JSON()方法来解析客户端发送过来的JSON格式数据 app.use(express.json()) // 配置内置中间件 , 调用 express.Url-encoded()方法来解析客户端发送过来的 Url-encoded格式数据 app.use(express.urlencoded({extended:false})) app.post('/a', (req, res) => { // 在服务器,可以使用 req.body这个属性,来接收客户端发送过来的请求体数据 // 默认情况下 如果没有配置内置解析表单数据体的中间件,则 req.body 默认是undefined console.log(req.body) res.send('ok') }) app.post('/book', (req, res) => { // 在服务器中 req.body 中可以获取表单以 JSON 或 Url-encoded 格式的表单数据 console.log(req.body) res.send('okk') }) app.listen(80, () => { console.log('http://127.0.0.1') })
19.自定义解析表单数据的中间件
// 导入 express 服务器模板 const express = require('express') // 导入 node.js 内置的querystring 模块 调用querystring.parse()来解析客户端请求提数据 const Qs = require('querystring') // 创建express实例 const app = express() // 这是解析表单数据的中间件 app.use((req, res, next) => { // 声明一个来接收拼接好的字符串变量 let str = '' // 监听 req.data的事件 来获取客户端请求体数据 req.on('data', (chunk) => { str += chunk }) // 监听客户端请求体数据发送完成的事件 req.on('end', () => { // console.log(str) // 调用 qs 中的parse()方法 把字符串格式的请求体解析数据为对象 const body = Qs.parse(str) // console.log(body) // 将解析好的 body 挂载在req对象身上 ,因为多个中间件共享同一个 req 或 res 对象 req.body = body next() }) }) app.post('/a', (req, res) => { res.send(req.body) }) // 启动服务器 app.listen(80, () => { console.log('http://127.0.0.1') })
20.封装自己的解析请求体数据的中间件
// 导入 node.js 内置的querystring 模块 调用querystring.parse()来解析客户端请求提数据 const Qs = require('querystring') bodyparse = (req, res, next) => { // 声明一个来接收拼接好的字符串变量 let str = '' // 监听 req.data的事件 来获取客户端请求体数据 req.on('data', (chunk) => { str += chunk }) // 监听客户端请求体数据发送完成的事件 req.on('end', () => { // console.log(str) // 调用 qs 中的parse()方法 把字符串格式的请求体解析数据为对象 const body = Qs.parse(str) // console.log(body) // 将解析好的 body 挂载在req对象身上 ,因为多个中间件共享同一个 req 或 res 对象 req.body = body next() }) } // 向外暴露属性 module.exports = bodyparse
21.使用express 编写 GET 和 POST 接口
注意 : 在 express 服务器中 GET 请求 只能通过 req.query 获取客户端发送过来的 查询字符串
在express 服务器中 POST 请求 只能通过 req.body 获取客户端发送过来的请求提数据 注意: 要解析post请求数据才能获取
设置解析urll-encoded全局中间件 app.use(express.urlencoded({extenede:false}))
// 导入 express 服务器 模块 const express = require('express') // 创建 express()实例对象 const app = express() // 导入自定义 apiRouter模块 const router = require('./14-apiRouter') // 注册全局 url-encoded 解析中间件 用来解析post请求过来的数据体 app.use(express.urlencoded({ extenede: false })) // 将导入 router 注册 为全局中间件 app.use('/api', router) // 启动服务器 app.listen(80, () => { console.log('http://127.0.0.1') })
const express = require('express') // 创建 路由实例对象 const router = express.Router() // 挂载对应的路由 router.get('/get', (req, res) => { // 获取客户端发起请求的数据 const query = req.query // 将响应的状态和数据发送给客户端 res.send({ status: 1, msg: "GET 请求成功!!!", data: query }) }) // 挂载对应的路由 router.post('/post', (req, res) => { const body = req.body res.send({ status: 1, msg: 'POST 请求成功!!!', data: body }) }) // 将router属性对外共享 module.exports = router
22.解决跨域接口问题
使用 cors 第三方中间件解决跨域接口问题 注意: cors 是基于 express模板的第三方中间件
运行 npm i install cors 安装中间件
使用 const cors = require(‘cors’) 导入中间件
在路由之前调用 app.use(cors())配置中间件
23.使用JSONP解决跨域 写接口
// 优先 创建 JSONP 接口 注意 : 要写在 cors 中间件之前 app.get('/api/jsonp',(req,res)=>{ // 实现 jsonp 接口的过程 // 1. 得到客户端发送过来的请求函数名称 const funcName = req.query.callback // 2. 定义一个数据 用来返回给客户端 const data = {name:'zs',age:18} // 3. 使用字符串拼接 将函数名和数据进行拼接 const scriptStr = `${funcName}(${JSON.stringify(data)})` // 4. 将拼接好的函数发送给客户端 res.send(scriptStr) })
测试 jsonp接口
// 测试JSONP接口 $('#btnJSONP').on('click',function(){ $.ajax({ method : 'GET', url : 'http://127.0.0.1/api/jsonp', dataType:'jsonp', success: function(res) { console.log(res) } }) })