Express

Express


基于 Node.js 平台的 Web 开发框架

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

app.use('/', (req, res) => {  	//路由
  res.send('hello')				//响应信息
})

app.listen(8080, () => {		//监听端口
  console.log('正在监听8080...');
})

执行顺序

在使用app.use()配置路由时,类似正则匹配

如"/index"因为有"/“所以既会匹配”/index"也会匹配"/"的路由

这时候就基于路由排列顺序执行,且只会执行第一个匹配到的路由



中间件

app.use后的回调函数也称为中间件,后面可以接多个回调函数,也可以将其组合封装成数组

回调函数中有第三个参数next,类似迭代器,用于顺序执行中间件栈

中间件的功能:

1.执行任何代码。
2.修改请求和响应对象。
3.终结请求-响应循环。
4.调用堆栈中的下一个中间件。


中间件栈

app.use('/', (req, res, next) => {  //多个中间件组成中间件栈
  console.log('1');
  next()
}, (req, res, next) => {
  console.log('2');
  next()
}, (req, res) => {
  console.log('3');
})

------------------------------------------

const middlewares = [(req, res, next) => {   //或用数组封装
  console.log('1');
  next()
}, (req, res, next) => {
  console.log('2');
  next()
}, (req, res, next) => {
  res.send('3')
  next()
}]
app.use('/', middlewares)

会将所有匹配到的路由的中间件组成一个中间件栈,只要有next()就能执行下一个中间件

app.use('/', (req, res, next) => {
  console.log('1');
  next()
}, (req, res, next) => {
  console.log('2');
  next()
}, (req, res, next) => {
  res.send('3')
  next()
})

app.use('/i', (req, res) => {  //多个app.use()的中间件同样为栈
  console.log('hello11');
})
//访问localhost:xxxx/i  输出结果1,2,hello11

res.send()并不会影响中间件栈的执行,只有当其中一个中间件没有next()时,才会停止后续中间件的执行


无论是全局还是局部中间件 先后顺序都是按照在代码中的代码书写顺序

写在next()后的代码同样会执行

next()本质上就是下一个中间件函数

app.use((req, res, next) => {
  console.log('1 fired')
  next()
  console.log('1 end')
}, (req, res, next) => {
  console.log('2 fired')
  next()
  console.log('2 end')
}, (req, res, next) => {
  console.log('3 fired')
})
/* 输出结果为
1 fired
2 fired
3 fired
2 end
1 end
*/

当中间件不加路由时,所有请求都会调用一次
app.use('/i', (req, res) => {  
  console.log('hello11');
})
app.use(() => {				//没有路由所以相当于都会匹配,每次请求均会执行
  console.log(0);
})



express中间件


路由中间件

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

route.get('/', (req, res) => {
  res.send('我是11')
})
route.get('/index', (req, res) => {
  res.json(req.query) 	//返回请求参数
})
route.post('/index', (req, res) => {
  res.send(req.body)	//返回请求体
})
route.put('/', (req, res) => {
  res.send('我是22')
})
route.patch('/', (req, res) => {
  res.send('我是33')
})
route.delete('/', (req, res) => {
  res.send('我是44')
})


route.all('/', (req, res) => {   //特殊请求方式,只要路由符合 所有的请求都会响应(简化代码)
  res.send('我是all')
})

module.exports = {
  route
}

此时与http的路由类似,只有路径相同且route方法也与请求方式匹配才会响应

route.get('/index', (req, res) => { //当请求路由为/index且为get请求才有响应(其他请求不作响应)
  res.json(req.query)
})

路由通配符

router.use('/a/*/d',(req, res)=>{
	console.log('测试通配符')
})
// 此时*号进行任意值任意长度的匹配
router.use('/k/:kfc',(req, res)=>{
	console.log('获取params参数' , req.params)
})
// /k/后的值被变量kfc接收 并可以通过req.params访问

设置响应头

res.set('Content-Type','application/json; charset=utf-8')
或
res.header('Content-Type','application/json; charset=utf-8')



http-proxy-middleware中间件

const { createProxyMiddleware } = require('http-proxy-middleware');

app.use('/api', createProxyMiddleware({ target: 'http://www.example.org', changeOrigin: true }));

// http://localhost:3000/api/foo/bar -> http://www.example.org/api/foo/bar

cors中间件

const cors = require('cors')
app.use(cors()) // 解除跨域限制

jsonwebtoken中间件

在中间件中将token加密挂载到req中,后续业务逻辑就能通过req.sign进行调用

const jwt = require('jsonwebtoken')
app.use((req, res, next)=>{
	req.sign = (res)=>{
		return jwt.sign(res, '123456')
	}
	next()
})

鉴权

app.use((res, req, next) => {
  const { url } = req
  if(url === '/user/login') return next()
  // authorization 惯例携带token的参数
  const tk = req.header.authorization
  try{
    const decode = jwt.verify('tk', '123456')
    req.decode = decode
    next()
  } catch(e){
    res.status(401).end()
  }
})

// 实际中一般token格式为 authorzation:'Bear tk'  tk为加密的token

express内置中间件

用于托管静态文件,如果使用多个静态目录则多次调用此中间件

app.use(express.static('public')) //public静态文件夹名

express设置响应头跨域

注意需要在注册路由之前

app.all('*',function (req, res, next) {
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Headers', '*');
  res.header('Content-Type', 'application/json;charset=utf-8');
  res.header('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE, OPTIONS');
  next();
});




controller抽离

当中间件的让业务逻辑过多时,需要把逻辑进行模块化

即将controller抽离出来成为一个单独的模块 在路由中间件引用




cookie与session


服务端响应可以设置cookie与cookie-session

session本质上就是cookie 是加密后的cookie

响应设置cookie

app.get((req, res)=>{
	const _d = new Date()
	_d.setSeconds(_d.getSeconds() + 5)
	res.cookie('abc', 123, {
	expires: _d, // 约定cookie到期时间
 	path: '/',   // 约定cookie的可访问路径
 	httpOnly: true
               // httpOnly 是否值允许请求的时候对cookie进行操作 不允许js去操作这个cookie
	})
	res.send('ok')
})

通过response响应设置cookie 以及路径、过期时间、是否能被js修改

响应设置的cookie在请求时也会携带 但需要中间件cookie-parse

const cookieParser = require('cookie-parser')
app.use(cookieParser())
app.use((req,res)=>{
  console.log(req.cookies)
  res.end()
})



响应设置session

需要先引入中间件cookie-session

const cookieSession = require('cookie-session')
app.use(cookieSession({
	name: 'session',  		// 保存到客户端的cookie的name
	secret: '123456',		// 加密密钥
	maxAge: 24*60*60*1000	// 过期时间
}))
app.use((req,res)=>{
  req.session.view = 1		// 设置一个session的值
  res.send('ok')
})

app.use((req,res)=>{
  console.log('session', req.session)	// 通过 req.session 也可以读取session
  res.send('ok')
})



express脚手架


安装脚手架

npm install express-generator -g 

创建项目

express demo

修改端口

在浏览器中使用 localhost:3000访问,默认的端口就是3000

app.js修改端口配置

process.env.PORT = 2000;





渲染


页面渲染(render)分为客户端渲染和服务器渲染

SSR(Server Side Render)
CSR(Client Side Render)

express的渲染模板

ejs
pug
jade
art-template


art-template模板


下载art-template以及express-art-template

yarn add art-template express-art-template -S

环境配置

//view engine setup
const path = require('path')
app.engine('art', require('express-art-template'))
app.set('view options', { //注意此处与官网不同
  debug: process.env.NODE_ENV !== 'production',
  escape: false           //是个坑,转化HTML5代码
})
app.set('views', path.join(__dirname, './views'));
app.set('view engine', 'art')

同文件夹下创建view文件夹 在其中创建list.art用于处理数据

{
	"ret": true,
	"data": {{data}}					//这里的{{data}}中的data为下方res.render()处理完的数据
}

然后在controller中的中间件(此处为list)返回数据

const list = () => {
  	let dataArray=[]
	for(let i = 0; i < 100; i++){
		dataArray.push('line' + i)			//生成模拟数据
	}
	res.set('Content-Type','application/json; charset=utf-8') 
	res.render('list',{						//express本身没有render() 下载模板后才能使用
		data: JSON.stringify(dataArray)		//读取list.art下的data并赋值
	})  
}
export.list = list

以上均为后端!!!


前端渲染

const str = `
  <ul> 
  {{each data}}   		 //循环data
    <li>{{$value}}</li>  //值放入li中
    {{/each}}
  </ul>
`
let html = template.render(str,{data: result.data})   
		//这里的result为ajax请求后端返回的成功回调结果
		//此处省略了外部的ajax

$('#list').html(html)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Raccom

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值