摸一下 express
安装
npm i express -S
或使用官方生成器npx express-generator
1. 基本使用
创建 app
const express = require('express');
const app = express();
app.listen(3000, () => { console.log('http://localhost:3000') })
各种请求方式
app.get('/', (req, res) => {
res.send('index get');
});
app.post('/', (req, res) => {
res.send('index post');
});
app.put('/', (req, res) => {
res.send('index put');
});
app.delete('/', (req, res) => {
res.send('index delete');
});
路由嵌套
app.get('/login', (req, res) => {
res.send('login get');
});
app.get('/users/jufjzq', (req, res) => {
res.send('users jufjzq');
});
动态路由
app.get('/users/:id', ({ params: { id } }, res) => {
res.send('动态 users ' + id);
});
路由传参
- 获取 get 参数
app.get('/params', (req, res) => {
const { query } = req;
res.send(query);
});
- 获取 post 参数
const bodyParser = reuqire('body-parser') // npm i body-parse -S
app.use(bodyParser.urlencoded({ extended: false })) // parse application/x-www-form-urlencoded
app.use(bodyParser.json()) // parse application/json
2.使用 EJS 模版渲染
ejs 就是渲染 html
安装:npm i ejs -S
配置模版引擎:app.set('view engine', 'ejs')
注意:
1. ejs 不需要主动引入,只需要配置上面的代码就可以了
2. ejs 默认加载 views 文件夹下的 *.ejs
文件
views/index.ejs
<h1>ejs index page</h1>
app.js
const express = require('express');
const app = express();
app.set('view engine', 'ejs'); // ejs 不需要引入,只需要配置
app.get('/', (req, res) => {
res.render('index', {});
});
app.listen(3000, () => {
console.log('http://localhost:3000');
});
常用模版语法
- 渲染变量:
<%= 变量 %>
- 渲染html:
<%- html字符串 %>
- 条件判断:
<% if(true) {%>
do something...
<% } %>
- 在模版中引入其他模版:
<%- include('path.ejs') %>
自定义 ejs 文件夹
app.set('views', `${__dirname}/views`)
设置 ejs -> html
模版中明明是 html 后缀但是用的是 .ejs
后缀,就很不爽
const ejs = require('ejs');
app.engine('html', ejs.__express);
app.set('view engine', 'html');
这样设置以后好像是 html/ejs 都可以渲染
3. 静态文件托管
+dir /static/css/index.css
app.use(express.static('static'))
html
<link rel="stylesheet" href="/css/index.css">
中间件
- 应用级中间件
- 路由中间件(不常用)
- 错误处理中间件
app.use((req, res) => {
res.status(404).send('404');
});
- 内置中间件
app.use(express.static('static'))
- 第三方中间件
body-parser 获取 post 传参
操作 cookie
cookie 是一个用途想法很简单的东西,同一个域下的所有网站共享数据
但现在的都是单页应用,不用 cookie 也可以实现所有页面共享
const cookieParser = require('cookie-parser'); // npm i cookie-parser -S
app.use(cookieParser())
- 设置/获取 cookie
res.cookie( key, value, options);
res.cookies( key )
- 设置过期时间
res.cookie( key, value, {
maxAge: 1000 * 60 * 12 // 12 小时
})
- 设置二级域名共享
res.cookie( key, value, {
domain: '.jufjzq.com'
})
- 指定 path 访问 cookie 权限
指定后只能在该 path 内访问到 cookie 其他页面没有值
res.cookie( key, value, {
path: '/user'
})
- cookie 签名/加签/加密
1. 配置 cookie-parser 签名
app.use(cookieParser('itying'))
2. 使用签名
res.cookie( key, value, {
sign: true
})
3. 获取签名 cookie (解密)
res.signCookies.key
使用 Session
Session 是另一种记录客户状态的机制,保存在服务器上安全可靠,但会给服务器压力
Cookie 单个 4K 左右,一个站点最多 20 条,Session 基于 Cookie 但没限制
- cookie:浏览器客户端状态持久化
- Session:服务器上状态持久化
Session 工作流程
- 浏览器访问服务器,服务器创建 Session 对象,生成类似 key: value 结构
- 将 key(cookie) 返回客户端,客户端存储
- 下次访问客户端携带 key(Cookie) 至服务器上,找到对应 Session(value)
安装/引入
/* 引入 session 中间件 */
const session = require('express-session'); // npm i express-session -S
配置 session 中间件
app.use( session({
session({
secret: 'sign', // 服务端签名
resave: false, // 强制保存即使无变化
saveUninitialized: true, // 强制存储未初始化的 Session
cookie: {
secure: false, // 只接受 https 协议( 只有 https 才能访问 cookie )
maxAge: 1000 * 60 * 30, // 配置过期时间
},
rolling: true, // 访问刷新过期时间
})
}))
基本使用
app.get('/', (req, res) => {
const { uname } = req.session
if(uname) {
return res.send(`${uname} - 欢迎`)
}
res.send('未登录')
})
app.get('/login', (req, res) => {
req.session.uname = '张三'
res.rend('登录成功')
})
- 销毁所有 session
req.session.destroy( err => {
throw new Error(err)
})
或
req.session.cookie.maxAge = 0 // 重设过期时间立马过期
- 销毁指定 session:
req.session.uname = ''
分布式架构共享 Session
为了负载均衡,在全国不同地方都有设置服务器,但是 session 只存储在内存中,所以如果 北京的服务器生成了 session 如果上海也要拿到到就必须存入数据库
北京
前端 dist -- nginx -- { 上海 } -- mongodb
深圳