express入门


express

npm i express

1 创建一个基本的express服务器

// 引入express
const express = require('express')
// 创建express实例
const app = express()
// 在app上挂在路由
app.get('/list',(req, res)=> {})
app.post('/add', (req, res)=> {})
// 启动服务器,监听端口
app.listen(1001, ()=> {
})

2 获取客户端传递的参数

2.1 通过 res.query()获取 get请求url中传递的参数

// 请求地址 http://localhost:1001/list?id=1?status=2
app.get('/list', (req, res)=> {
	console.log(req.query)
	// {id: 1, status: 2}
})

2.2 通过res.params可以获取到,url中,通过:匹配到的动态参数

// 请求地址 http://localhost:1001/add/1/张三
app.get('/add/:id/:name', (req, res)=> {
	console.log(req.params)
	// {id: 1}
})

2.3 获取post请求参数

// 通过 express.json() 这个中间件,解析表单中的 JSON 格式的数据,没有使用这个中间件res.body为undefined
app.use(express.json())
app.use(express.urlencoded({ extended: true }))
app.post('/add', (req, res)=> {
  res.send({
    code: 0,
    msg: '操作成功',
    data: [req.body]
  })
})

3 express.static() 静态托管

3.1 托管一个静态资源文件

// 这就就可以访问public文件下的内容了
// 如果服务运行在  http://localhost:1001
// 通过http://localhost:1001/index.html 就可以访问到public文件下index.html文件
app.use(express.static('./public'))

3.2 托管多个静态资源文件

如果托管多个静态资源目录,就多次调用express.staitc()

// node会按照调用的顺序去执行查找静态资源
// 如果两个都有index.js,在第一个中找到直接返回,就不会去第二个找了
// 如果第一个没找到,回去第二个中查找
app.use(express.static('./public'))
app.use(express.static('./file'))

3.3 挂载静态资源的前缀

// 没有添加前缀
// http://localhost:1001/index.html   就能访问
app.use(express.static('./public'))
// 添加前缀
// http://localhost:1001/file/index.html   才能访问
app.use('file',express.static('./file'))

4 nodemon安装使用

全局安装npm install -g nodemon

启动命令nodemon .\index.js
在这里插入图片描述

5 路由

客户端的请求服务端的处理函数映射关系

路由包含三部分:请求方式请求地址处理函数

app.post(path, (req, res)=> {})
app.get(path, (req, res)=> {})

5.1 路由的基本使用

app.get('/list', ()=> {})
app.post('/add', ()=> {})

5.2 模块化路由

为了方便对路由进行模块化的管理,不建议将路由挂载到app(express实例)上,而是推荐将路由抽离为单独的模块

具体步骤:

  1. 创建路由模块对应的.js文件
  2. 调用express.Router()创建一个路由对象
  3. 向路由对象上挂在路由
  4. 通过module.exports向外共享路由对象
  5. 使用app.use注册路由模块

示例代码:
在这里插入图片描述

Router-------路由模块
index.js------入口文件

index.js文件

// 引入express模块
const express = require('express')
// 引入user路由模块
const user = require('./Router/user')
// 引入manager路由模块
const manager = require('./Router/manager')
// 创建express实例
const app = express()
// 注册中间件(中间件是按照顺序执行的)
app.use(express.json())
app.use(express.urlencoded({ extended: true }))
app.use('/user', user)
app.use('/manager', manager)

app.listen(1002, ()=> {
  console.log('server running at http://127.0.0.1:1002')
})

user.js模块


// 引入express模块
const express = require('express')

// 创建Router实例
const Router = express.Router()

// 在Router上挂载路由
Router.get('/list',(req, res)=> {
  res.send(req.query)
  // http://127.0.0.1:1002/user/list?name=lily&age=20
  // {"name":"lily","age":"20"}
})

Router.post('/add',(req, res)=> {
  res.send(req.body)
  // http://127.0.0.1:1002/user/add 入参为{"message":"这是一条测试消息"}
  // {"message":"这是一条测试消息"}
})

// 向外暴露Router
module.exports = Router

manager模块

const express = require('express')
const Router = express.Router()

Router.get('/list', (req, res)=> {
  res.send(req.query)
  // http://127.0.0.1:1002/manager/list?id=1&name=Tom&age=20
  // {"id":"1","name":"Tom","age":"20"}
})

Router.post('/add', ()=> {
  res.send(req.body)
  // http://127.0.0.1:1002/manager/add 入参是{"message":"这是一条测试消息"}
  // {"message":"这是一条测试消息"}
})

module.exports = Router

6 express中间件

中间件是业务处理环境中的中间处理环境,有输入有输出。

客户端请求 ===> 中间件1 ===> 中间件2 ===> 中间3 ===> 最终处理,并详情此次请求 ===> 客户端

  1. 通过app.use()注册全局中间件

    const express = require('express')
    const app = express()
    // 定义中间件函数
    const momFun = (req, res, next)=> {
    	console.log('我是全局中间件')
    	next()
    }
    // 注册全局中间件
    app.use(momFun)
    // 简化形式
    app.use((req, res, next)=>{
    	next()
    })
    app.get('/', (res, req)=> { ... })
    
  2. 局部中间件
    回调函数中,有形参next为中间件函数,没有形参next为路由函数

    const express = require('express')
    const app = express()
    
    // 中间件函数
    app.get('/user', (req, res, next)=> {
    	next()
    })
    // 路由函数
    app.get('/user', (req, res)=>{})
    

6.1 中间件的格式

// 在回调函数中,包含形参nextnext()是多个中间件连续调用的关键,它表示把流转关系转交到下一个中间件或者路由

const express = require('express')
const app = express()
// 定义一个全局中间件
app.use((req, res, next)=>{
	next()
})

app.listen(1003, ()=>{})

6.2 定义一个中间件函数

const express = require('express')
const app = express()
// 定义一个全局中间件
app.use((req, res, next)=>{
	next()
})

app.get('/list',(req, res)=> {
	res.send('哈哈')
})

app.listen(1003, ()=>{})

6.2.1 定义一个全局生效的中间件

				上面的例子就是注册全局中间件的例子

6.2.2 定义一个局部中间件

不使用app.use()注册的中间件,而是放在路由的参数中

const express = require('express')
const app = express()
const fun1 = function(req, res, next) {
	// ...
	next()
}
app.get('/list', fun1, (req, res)=> {
	// ....
})

代码示例:

const express = require('express')
const app = express()

app.use((req, res, next)=> {
  req.number = 10
  next()
})

fun1 = (req, res, next)=> {
  req.myParams = {
    value: '哈哈哈',
    id: 1
  }
  req.str = '11111'
  next()
}

app.get('/list1', (req, res)=> {
  console.log(req.number) // 10
  req.number = 20
  console.log(req.myParams) // undefined
  console.log(req.str)  // undefined
  res.send('操作成功')
})
app.get('/list2', fun1, (req, res)=> {
  console.log(req.number) // 10
  console.log(req.myParams) // { value: '哈哈哈', id: 1 }
  console.log(req.str)    // 11111
  res.send('操作成功')
})

app.listen(1000)
  • 全局中间件中设置的req参数,可以在所有路由中获取,
  • 局部中间件中设置的req参数,只能在使用局部中间件的路由中获取
  • 在路由中只能获取req参数,不能设置参数,设置也不生效

6.2.3 同时使用多个局部中间件

const express = require('express')
const app = express()
fun1 = (req, res, next)=> {
	// ... 
	next() 
}
fun2 = (req, res, next)=> {
	// ... 
	next() 
}
fun3 = (req, res, next)=> {
	// ... 
	next() 
}

app.get('/list', fun1, fun2, fun3, (req, res)=> {
	// ....
})
app.listen(1000)

6.3 中间件的作用

多个中间件见,共享同样的req和res,我们可以给req和res添加方法和属性,给下面的中间件或者路由使用,使代码更优雅

6.4 中间件分类

  • 应用级别的中间件
  • 路由级别的中间件
  • 错误级别的中间件
  • Express内置的中间件
  • 第三方的中间件

6.4.1 应用级别中间件

通过app.useapp.get()app.post()绑定到app实例上的中间件

6.4.2 路由级别中间件

通过Router.use()Router.get()Router.post()绑定到Router实例上的中间件

const express = require('express')
const Router = express.Router()
Router.use((req, res, next)=>{
	//	....
	next()
})
Router.get('/list', fun1, (req, res)=>{
	// ....
})
module.exports = Router

6.4.3 错误级别中间件

专门用来捕获异常,格式:处理函数有4个形参,分别是errreqresnext

app.get('/list', (req, res)=> {
	throw new Error('抛出一个错误')
	res.send('请求成功')
})
app.use((err, req, res, next)=>{
	console.log('发送错误 ' +  err。message)
	res.send('Erroe!' + err.message)
})

错误中间件必须注册在所有路由之后

6.4.4 内置中间件

  1. express.static() 托管静态资源
app.use(express.static('./public'))
  1. express.json() post解析json请求体数据
app.use(express.json())
  1. express.urlencodeed() 解析URL-encoded格式的请求体数据
app.use(express.urlencoded({ extended: false }))

7 cors中间件解决跨域问题

  1. 运行 npm install cors 安装中间件
  2. 使用 const cors = require('cors') 导入中间件
  3. 在路由之前调用 app.use(cors()) 配置中间件
const express = require('express')
const cors = reqiure(''cors)

const app = express()
app.use(cors())

7.1 CORS响应头

  1. Assess-Control-Allow-Origin 哪些URL可以访问
Assess-Control-Allow-Origin:  origin  |  *
  • origin - 指定允许访问的URL
  • *-----通配符 ,所有的URL都能访问
res.setHeader('Assess-Control-Allow-Origin': '*')
  1. Assess-Control-Allow-Headers 对格外的请求头进行申明
res.setHeader('Assess-Control-Allow-Headers', 'xxxxx')
  1. Assess-Control-Allow-Methods 指定允许客户端发起的请求方式(get,post,put,delete)
res.setHeader('Assess-Control-Allow-Methods', 'POST, GET, DELETE, PUT')

res.setHeader('Assess-Control-Allow-Methods', '*')

7.2 简单请求

  1. 请求方式只能是 GET POST HEAD
  2. 请求头不包含自定义请求头

满足以上条件才为简单请求

7.3 预检请求

  1. 请求方式为 GET POST HEAD 以外的
  2. 请求头包含自定义请求
  3. 想服务器发送了application/json格式的数据

满足上面一个条件即为预检请求

在 浏览器 和 服务器正式通信之前, 浏览器会先发送一个 OPTION 请求进行预检, 以获知服务器是否允许该请求。所以称此次请求为“”预检请求“,服务器成功相应预检请求后,才会发送真正的请求,并携带真实参数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值