res.setHeader():设置响应的头信息,同一个路由中只能使用一次
res.writeHead():设置响应的头信息,同一个路由中只能使用一次
res.write():设置响应的内容,可以多次使用
res.end():结束响应,同一个路由中只能使用一次
res.send():设置响应的内容,相当于原生nodejs中的res.setHeader()和res.end()这两个方法,同一个路由中只能运行一次;
res.sendFile():将某个文件内容读取出来并作为响应返回给客户端,同一个路由中只能运行一次;
把前端给的文件一一归类。
1、html页面放在views文件夹
2、静态资源放在static或public
3、配置一些post中间件(因为要接收post传递过来的参数)
4、配置开放静态资源的中间件
注意:当表单中含有文件上传的表单项时要把表单的编码格式设置为流媒体格式:enctype="multipart/form-data"
在express框架中使用第三方formidable包来处理含有文件上传的表单:
app.post('/zhuce', (req, res) => {
let curPath = path.join(__dirname, 'uploads');
//判断文件或目录是否存在:
if (!fs.existsSync(curPath)) { //uploads目录不存在时则创建该目录
//创建目录:
fs.mkdirSync(curPath);
}
// multiples: true 支持多文件上传
//uploadDir:用来指定文件上传成功后的存放位置
const form = formidable({ multiples: true, uploadDir: curPath });
// console.log(form);
//form.parse():用来处理含有文件上传的表单
form.parse(req, (err, fields, files) => {
console.log(err, fields, files, 7777);
});
});
保留原文件名:
生成及其他文件名:
1)年月日时分秒 + 8位随机数
2)使用第三方模块uuid,使用方法:uuid - npm。
app.post('/zhuce', (req, res) => {
let curPath = path.join(__dirname, 'uploads');
//判断文件或目录是否存在:
if (!fs.existsSync(curPath)) { //uploads目录不存在时则创建该目录
//创建目录:
fs.mkdirSync(curPath);
}
// multiples: true 支持多文件上传
//uploadDir:用来指定文件上传成功后的存放位置
const form = formidable({ multiples: true, uploadDir: curPath });
// console.log(form);
//form.parse():用来处理含有文件上传的表单
form.parse(req, (err, fields, files) => {
if (err) { //含有文件上传的表单处理失败
res.send('文件上传失败');
} else { //含有文件上传的表单处理成功
//要上传的原始文件名
let fileNames = files.pic.name;
let fArr = fileNames.split('.');
//获取文件扩展名:
let extName = fArr[fArr.length - 1]
// console.log(fArr, extName);
//将上传成功后的临时文件重命名成正式文件名:
fs.renameSync(files.pic.path, `${curPath}/${uuidv4()}.${extName}`);
res.send('Yes');
}
});
});
为什么要使用cookie、session?
因为http协议是无状态的协议,也就是服务器不会保存客户端的状态,当我们使用了cookie或session之后可以让我们的系统有记忆功能。
Cookie的产生也是HTTP的特点所决定的。HTTP协议有一个非常重要的特点是无状态的,也就是说当客户端请求服务器,每一个请求和响应结束以后,这次的连接是马上断开的(也是为了释放资源)。同时服务器是不保留连接者相关的信息。这就说明了,Cookie要解决HTTP无状态的问题。
cookie默认有效时间为整个有效会话期间、cookie可以设置有效时间,session默认有效时间为整个有效会话期间、session不能设置有效时间;
有效会话期间:是指当打开某个浏览器开始访问系统到关闭整个浏览器之前这段时间称为有效会话期间。
cookie的大小限制在4KB左右、session没有限制;
cookie存储在客户端、相对不安全,session存储在服务端,相对安全;
cookie有数量限制:每个主机可以存放cookie的个数最多不能超过50个Cookie,session没有这方面的限制;
不同的浏览器之间不共享Cookie、session;
注意:获取cookie时要使用第三方cookie-parser中间件:
文档的参考地址: Express cookie-parser middleware - Express 中文文档 | Express 中文网
npm install cookie-parser
const cookieParser = require("cookie-parser"); // 引入cookieparser中间件
app.use(cookieParser()); // 使用cookie-parser中间件 全局开启cookie功用
res.cookie(key,value[,option])
参数说明:
option:可选参数,{ maxAge : ms} 过期时间,表示多长时间后过期。以毫秒为单位
文档的参考地址:Express 4.x - API Reference - Express 中文文档 | Express 中文网
req.cookies
1)/login路由中通过req.cookie方法设置cookie
2)/welcome路由中设置欢迎界面
3)设计“/user/edit”路由,如果登录了可以正常访问,如果未登录则不让访问(权限管理雏形)
const express = require('express');
const router = express.Router();
const path = require('path');
const fs = require('fs');
//显示登录界面:
router.get('/login', (req, res) => {
res.sendFile(path.join(__dirname, 'login.html'));
});
router.get('/mycookie', (req, res) => {
res.send(`${JSON.stringify(req.cookies)}`);
});
//处理用户登录的表单:
router.post('/denglu', (req, res) => {
//接收post方式的键值对格式发送的参数:
console.log(req.body);
let { user = '', pwd = '' } = req.body;
if (user == '' || pwd == '') {
res.send(``);
return;
}
//获取已注册的用户数据:
let uStr = fs.readFileSync(path.join(__dirname, 'user.json'));
let uObj = JSON.parse(uStr.toString());
if (user == uObj.user && pwd == uObj.password) {
//将登录成功的帐号保存到cookie中:
res.cookie('UNAME', user);
res.send(``);
// res.send(``);
} else {
res.send(``);
}
});
//欢迎界面:
router.get('/welcome', (req, res) => {
// let uname = req.query.uname ? req.query.uname : '';
//获取cookie:获取当前已登录的帐号
let uname = req.cookies.UNAME ? req.cookies.UNAME : '';
res.send(`欢迎您${uname}回来`);
});
module.exports = router;
Session是另一种记录用户状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在服务器上。当服务端使用Session后,那么服务器会把Session信息存储在服务器上,同时Session标识也会记录在对应客户端上。
Session存储在服务器
依赖cookie
可以存储任意类型
通过客户端的sessionid标识符区分Session
Session没有大小限制
注意:不管是设置session还是获取session都要使用cookie-session这个中间件。
文档的参考地址: Express cookie-session middleware - Express 中文文档 | Express 中文网
npm i cookie-session
const cookieSession = require("cookie-session"); // 引入cookieSession中间件
// 使用cookieSession 中间件
app.use(cookieSession({
name: 'sessionids',//sessionid的名称,默认可以省略
keys: ['secret1','secret2','secret3'], //密钥锁
// Cookie Options
//maxAge: 24 * 60 * 60 * 1000 // 24 hours , session的有效期
}))
req.session[key] = value
req.session
案例代码如下:
const express = require('express');
var cookieSession = require('cookie-session')
const app = express();
app.listen(3000, () => {
console.log('3000端口');
});
//使用第三方cookie-session中间件来操作session:
app.use(cookieSession({
name: 'cursessions', //cookie名称
keys: ['dsafdsa^^%$', 'yes*&^%ok'], //密钥
}))
//设置session:
app.get('/setsession', (req, res) => {
req.session.TEL = 110;
req.session.EMAIL = { "email1": "[email protected]", "email2": "[email protected]" };
res.send(``);
});
//获取session:
app.get('/getsession', (req, res) => {
let { TEL, EMAIL } = req.session;
console.log(TEL, EMAIL, 7779);
res.send(`获取session: ${JSON.stringify(req.session)}`)
});
为什么要使用ejs模板引擎?【重点】
使用ejs模板引擎可以让我们的界面与数据分离(比如:现在有1000条新闻,而这些新闻的展示界面风格都是一样的,这时我们只需要开发一个.html文件作为界面的模板文件,界面中的数据是动态获取到的), 可以提高开发效率,后期维护也方便。
1.下载ejs
npm i ejs
在项目中设置ejs模板引擎 【重点】
//设置ejs模板引擎:
app.set('view engine', 'ejs'); //设置模板引擎为ejs
//设置模板文件的存放位置
app.set('views', [path.join(__dirname, 'moban'), path.join(__dirname, 'views')]);
app.engine('html', require('ejs').__express); //将.html文件作为ejs模板文件来解析
3.在项目根目录下创建views文件夹
4.在views文件夹下创建模板文件
必须以 .ejs为后缀名
res.render('模板名称' [, data ])
参数说明:
参数1为模板名称不需要添加后缀,会自动寻找对应名称的.ejs文件
参数2为可选参数,向模板中传递的数据,必须是一个对象
5.3.2.1 数据渲染
<%=变量名 %>
5.3.2.2 分支
<% if( 条件 ){%>
<% }else{ %>
<% } %>
5.3.2.3 循环
<% for(let i=0;i<数组.length;i++){ %>
循环项
<% }%>
5.3.2.4 实例
说明:包含文件也是.ejs文件,无需携带后缀名
<%- include('公共文件路径') %>
后端程序代码如下:
const express = require('express');
const path = require('path');
const app = express();
app.listen(3000, () => {
console.log('3000端口');
});
//设置ejs模板引擎:
app.set('view engine', 'ejs'); //设置模板引擎为ejs
//设置模板文件的存放位置
app.set('views', [path.join(__dirname, 'moban'), path.join(__dirname, 'views')]);
app.engine('html', require('ejs').__express); //将.html文件作为ejs模板文件来解析
app.get('/mydemo', (req, res) => {
//注意:ejs模板引擎的默认模板文件的扩展名为.ejs
res.render('demo'); //渲染[展示]模板
});
//新闻详情页面:
app.get('/detail', (req, res) => {
// req.query.nid; //新闻id
let ntitle = '这是新闻标题标题标题标题标题';
let ncontent = '这是文本内容这是文本内容这是文本内容这是文本内容这是文本内容';
let stu = [{ "uname": "李四", "age": 20, "email": "[email protected]" },
{ "uname": "张三", "age": 21, "email": "[email protected]" },
{ "uname": "小明", "age": 16, "email": "[email protected]" }];
res.render('news_detail.html', { ntitle, ncontent, stu }); //渲染[展示]模板
});
news_detail.html模板文件代码如下:
Document
新闻标题为:
<%=ntitle %>
新闻内容为:
<%=ncontent %>
序号
姓名
年龄
邮箱
<% for(let i = 0;i
<%=i+1 %>
<%=stu[i].uname %>
<%=stu[i].age %>
<%
if(stu[i].age>18){
%>
成年
<% }else{ %>
未成年
<% } %>
<%=stu[i].email %>
<% } %>
5.3.2.5 包含文件
<%- include("header.html")%>