认识express
express是基于Node.js平台的web开发框架
作用和Node.js内置的http模块类似,是专门用来创建Web服务器的。
本质上Express就是一个npm的第三方包提供了快速创建Web服务器的便捷方法。
中文官网:expressjs.com.cn
express的作用:快速方便的创建 Web网站服务器和 API 接口服务器
express的基本使用
一、下载express包 npm i express@4.17.1
二、创建基本的web服务器
// 导入express const express = require('express') // 创建web服务器 const app = express() // 启动web服务器 app.listen(80,()=>{
console.log('express server running at http://127.0.0.1') })
讯享网
监听 GET、POST 请求
1、get请求一般用来请求获取数据、post请求一般作为发送数据到后台,传递数据,创建数据
2、get请求也可以传参到后台,但是传递的参数则显示在地址栏,安全性低,且参数的长度也有限制(2048字符)、 post请求则是将传递的参数放在request body中,不会在地址栏显示,安全性比get请求高,参数没有长度限制
3、get请求刷新浏览器或者回退没有影响、post请求则会重新请求一遍
4、get请求可以被缓存,也会保留在浏览器的历史记录中、post请求不会被缓存,也不好保留在浏览器的历史记录中
5、get请求通常是通过url地址请求、post常见的则是form表单请求
参数一、客户端请求的URL地址 参数二、请求队形的处理函数
req 请求对象 res 响应对象
通过 app.post( )方法监听客户端POST请求。
通过 app.get( )方法可以监听客户端的GET请求。
把内容响应给客户端
通过 res.send( )方法,可以把处理好的内容发送给客户端
讯享网// 监听客户的 GET 和 POST 请求,并向客户端响应具体内容 app.get('/user',(req,res)=>{
// 调用res.send方法向客户端响应一个JSON对象 res.send( {
name: 'zhangsan',age: 20, gender: '男'}) }) app.post('/user',(req,res)=>{
// 调用res.send向客户端响应一个文本字符串 res.send('请求成功') })
获取 URL 中携带的查询参数
通过 req.query 对象可以访问到客户端通过查询字符串的形式,发送到服务器的参数
app.get('/',(req,res)=>{
// 通过 req.query 可以获取到客户端发送过来的查询参数 // 默认情况下req.query是空对象 console.log(req.query) res.send(req.query) })
获取URL中的动态参数
通过 req.params 对象可以访问到URL中通过 :匹配到的动态参数
讯享网// 这里的 :id是一个动态的参数 app.get('/user/:id',(req,res)=>{
// req.params 是动态匹配到的 URL 参数,默认也是一个空对象 console.log(req.params) res.send(req.params) })
向 http://127.0.0.1/user/ABCD发送请求后得到响应:
{
"id": "ABCD" }
express.static 托管静态资源
express.static( )方法可以方便的创建一个静态资源服务器。 通过如下代码可以将public目录下的文件对外开放
讯享网app.use(express.static('public'))
注意:存放静态文件的目录名不会出现在URL中
想要托管多个静态资源目录,则多次调佣express.static( )即可
const express = require('express') const app = express() // 调用 express.static( ) 方法快速对外提供静态资源 // 传入文件目录位置 app.use(express.static('./clock')) app.use(express.static('./files')) // 启动服务 app.listen(80,()=>{
console.log('express server running at http://127.0.0.1') })
静态资源访问路径之前挂载前缀
app.use('/abc',express.static('./files')) :只需要在express.static 前面添加一个前缀即可
学习nodemon工具
该工具可以监听Node.js项目的代码,如果项目的代码发生了修改,该工具会自动重启项目,更方便开发和调试。
安装nodemon npm install -g nodmon
安装nodemon工具后,启动项目的方法:nodemon app.js
Express路由
路由的概念:就是映射关系。在express中路由指的是客户端的请求与服务器处理函数之间的映射关系
express中的路子分三部分组成
- 请求的类型(METHOD):GET或者POST
- 请求的地址PATH
- 处理函数HANDLER
app.METHOD(PATH,HANDLER)
一个简单的路由的例子
讯享网app.get('/',function(req,res){
res.send('hello,world') }) app.post('/',(req,res)=>{
res.send('got a POST request') })
路由的匹配过程
每一个请求到达服务器都需要先经过路由的匹配,匹配成功只会才会调用对应的处理函数。
会按照路由的顺序进行匹配。
如果请求类型和请求的URL同事匹配Express才会将这次请求转交给对应的function进行处理。
模块化路由
Express不建议将路由直接挂载到app上。为了方便对路由进行模块化的管理,一般将路由抽离为单独的模块。
一、创建路由模块对应的 .js 文件
二、调用 express.Router( )创建路由对象
三、向路由对象上挂载具体的路由
四、使用 module.exports向外共享路由对象
五、使用 app.use( )函数注册路由模块
创建路由模块
// 这是一个路由模块 //1、导入express const express = require('express') //2、创建路由对象 const router = express.Router() //3、挂载具体的路由 router.get('/user/list',(req,res)=>{
res.send('get user list') }) router.post('/user/add',(req,res)=>{
res.send('add new user') }) //4、向外到处路由对象 module.exports = router
注册路由模块
讯享网const express = require('express') const app = express() // 导入路由模块 const router = require('./05router') // 注册路由模块 //app.use(router) app.use('/api',router)// 统一添加访问前缀。 // 启动服务 app.listen(80,()=>{
console.log('router server running at http://127.0.0.1') })
app.use( )函数的作用就是用来注册全局中间件的。
express中间件
中间件指的就是业务处理过程中的中间处理环节,一般有输入与输出。
中间件是一个可访问请求对象(req)和响应对象(res)以及(next)的函数
中间件调用流程
当一个请求到达Express的服务器,可能连续调用多个中间件,对该请求进行预处理。
请求=>中间件处理next(中间件处理2 )=>next(中间件处理n)=>next(处理完毕)=>路由响应到客户端
中间件的格式
中间件本质上就是一个Function处理函数:格式如下:
app.get('/',function(req,res,next){
next( ) })
中间件的形参列表中必须包含next形参
next函数的作用
next函数时实现多个中间件连续调用的关键,表示把流转关系转件给下一个中间件或路由。
讯享网const express = require('express') const app = express() // 定义一个中间件 const mw = (req,res,next)=>{
console.log("这是一个简单的中间件函数") // 把流转关系转交给下一个中间件或路由 next() } app.listen(80,()=>{
console.log("http:127.0.0.1") })
全局生效的中间件
客户端发起任何请求,到达服务器之后都会被触发的中间件,即为全局生效中间件。
通过 app.use(中间件函数),即可定义一个全局生效中间件
示例代码:
const express = require('express') const app = express() // 定义一个中间件 const mw = (req,res,next)=>{
console.log("这是一个简单的中间件函数") // 把流转关系转交给下一个中间件或路由 next() } // 将 mw 注册为全局生效的中间件 app.use(mw) app.get('/',(req,res)=>{
console.log('调用了 / 路由') res.send('Home page.') }) app.get('/user',(req,res)=>{
console.log('调用了 /user 路由') res.send('uese page.') }) // 启动服务器 app.listen(80,()=>{
console.log("http:127.0.0.1") })
全局生效中间件的简化形式
讯享网app.use((req,res,next)=>{
console.log('这是一个简单的中间件函数的简写') next() })
中间件的作用
由于多个中间件之间可以共享一份req和res,所以我们可以再上有的中间件中统一为 req 或 res 对象添加自定义的属性或方法,宫下游的中间件或路由进行使用。
const express = require('express') const app = express() app.use((req,res,next)=>{
// 获取到请求到达服务器的事件 const time = Date.now() // 为req对象挂载自定义属性,从而把时间共享到后面所有的路由 req.startTime = time next() }) const a = app.get('/',(req,res)=>{
res.send('Home page.' + req.startTime) }) app.get('/user',(req,res)=>{
res.send('uese page.' +req.startTime) }) // 启动服务器 app.listen(80,()=>{
console.log("http:127.0.0.1") })
定义多个全局中间件
可以使用 app.use( ) 定义多个全局中间件。客户端请求到达服务器之后,会按照定义的先后顺序依次执行
讯享网const express = require('express') const app = express() // 定义了第一个全局中间件 app.use((req,res,next)=>{
console.log('调用了第一个全局中间件') next() }) // 定义了第二个全局中间件 app.use((req,res,next)=>{
console.log('调用了第二个全局中间件') next() }) // 定义一个路由,请求路由后先调用中间件 app.get('/user',(req,res)=>{
console.log('最后进入了路由') res.send('User page.') }) app.listen(80,()=>{
console.log("http://127.0.0.1") })
局部生效的中间件
不使用 app.use( ) 定义的中间件,都叫做局部生效中间件
const express = require('express') const app = express() // 定义中间件 const mw1 = (req,res,next)=>{
console.log('调用了局部生效的中间件') next() } // 创建路由 // mw1中间件只会在当前路由中生效 app.get('/',mw1,(req,res)=>{
res.send('Home page.') }) app.get('/user',(req,res)=>{
res.send('User page.') }) app.listen(80,()=>{
console.log("http://127.0.0.1") })
定义多个局部中间件的方法
讯享网app.get('/',mw1,mw2,(req,res)=>{
res.send('Home page.') }) app.get('/',[mw1,mw2],(req,res)=>{
res.send('Home page.') })
Express中间件初体验
中间件的使用注意事项
- 一定要在路由之前注册中间件
- 客户端发送过来的请求可以连续调用多个中间件进行处理
- 执行文中间件的业务代码后一定要调用next( )函数
- 在调用完 next( )之后,尽量不要再写额外代码,防止逻辑混乱
- 连续调用多个中间件,多个中间件之间共享req和res
中间件的分类(五大类)
一、应用级中间件
通过 app.use( ) 或 app.get( ) 或者 app.post( ) 绑定到实例上的中间件
二、路由级中间件
绑定到 express.Router( ) 实例上的中间件。
三、错误级别中间件
作用是捕获项目中可能会发生的异常错误,从而防止项目崩溃、错误级别中间件必须有四个形参: (err,req,res,next)
const express = require('express') const app = express() app.get('/',(req,res)=>{
// 认为的制造一个错误 throw new Error('服务器内部发生错误') res.send('Home page.') }) // 定义错误级别中间件来捕获整个项目的异常错误从而防止程序崩溃 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") })
注意:错误级别中间件一定要注册到所有路由之后
四、Expreww内置中间件
Express内置了三个常用中间件
1、express.static:快速托管静态资源的内置中间件:HTML/CSS/图片等。
2、express.json:解析 JSON 格式的请求体数据。4.16.0+node可用
app.use(express.json())
3、express.urlencodes:解析 URL-encoded 格式的请求数据。4.16.0+node可用,该中间件就是基于第三方body-parser 封装出来的。
app.use(express.urlencoded( { extended: false} ) )
示例:
讯享网const express = require('express') const app = express() // 通过express.json() 全局中间件解析表单中JSON数据 app.use(express.json()) // 通过express.urlencoded() 中间件来解析表单中的 url-encoded 格式的数据。 app.use(express.urlencoded( {
extended: false} )) app.post('/user',(req,res)=>{
// 服务器可以使用 req.body属性接收客户端发送的请求体数据 // 但没有配置表单解析数据的中间件,req.body 默认等于 undefined console.log(req.body) res.send('Ok!') }) app.post('/book',(req,res)=>{
// 通过 req.body 获取 url-encoded格式数据 console.log(req.body) res.send('Book!') }) app.listen(80,()=>{
console.log("http://127.0.0.1") })
五、第三方中间件
非 Express 内置的,第三方开发出来的中间件。可以按需下载,如 body-parser 中间件
1、安装: npm i body-parser 2、导入 3、注册使用
const express = require('express') const app = express() // 配置解析表单数据的中间件 const parser = require('body-parser') // 注册该中间件 app.use(parser.urlencoded( {
extended: false })) app.post('/user',(req,res)=>{
// 未配置解析中间件默认req.body值为undefined console.log(req.body) res.send('Ok!') }) app.listen(80,()=>{
console.log("http:127.0.0.1") })
案例:尝试自定义一个中间件
讯享网const express = require('express') // 导入 querystringify模块,该内置模块其提供的parse()可以将查询字符串解析成对象格式 const qs = require('querystringify') const app = express() app.use((req,res,next)=>{
// 定义存储数据的字符串 let str = '' // 监听req的dat事件 req.on('data',(chunk)=>{
str += chunk }) // 监听req的end事件 req.on('end',(chunk)=>{
// 把字符串格式的请求数据解析成对象 req.body = qs.parse(str) next() }) }) // 路由 app.post('/user',(req,res)=>{
res.send(req.body) }) // 启动服务器 app.listen(80,()=>{
console.log("http:127.0.0.1") })
还可以将自定义中间件封装成模块
const qs = require('querystringify') const bodyParser = (req,res,next)=>{
// 定义存储数据的字符串 let str = '' // 监听req的dat事件 req.on('data',(chunk)=>{
str += chunk }) // 监听req的end事件 req.on('end',(chunk)=>{
// 把字符串格式的请求数据解析成对象 req.body = qs.parse(str) next() }) } module.exports = bodyParser
使用express写接口
创建API路由模块
讯享网//创建路由模块 const express = require('express') const router = express.Router() //在这里挂载对应的路由 module.exports = router -------------------------------------- const express = require('express') const app = express() // 导入路由模块 const router = require('./19APIrouter') // 注册路由模块到app app.use('/api',router) // 启动服务器 app.listen(80,()=>{
console.log("express server running at http:127.0.0.1") })
编写 GET 接口与 POST 接口
const express = require('express') const router = express.Router() //在这里挂载对应的路由 router.get('/get',(req,res)=>{
// 通过 req.query 获取客户端,通过查询字符串,发送到服务器的数据 const query = req.query //调用 res.send() 方法向客户端响应处理结果 res.send({
status:0, // 0表示处理成功,1表示处理失败 msg:'GET 请求成功', // 状态描述 data: query // 客户端的数据 }) }) //在这里挂载对应的路由 router.post('/post',(req,res)=>{
// 通过 req.body 获取请求体中包含 url-encoded 格式的数据 const body = req.body //调用 res.send() 方法向客户端响应处理结果 res.send({
status:0, // 0表示处理成功,1表示处理失败 msg:'POST 请求成功', // 状态描述 data: body // 客户端的数据 }) }) module.exports = router
接口的跨域问题
以上的GET和POST接口存在跨域的问题
解决方案:
一、CORS(主流方案)
二、JSPNP(只支持GET请求)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/17548.html