(一)express 介绍
(二)express 使用
1、express 下载
2、express 初体验
(三)express 路由
1、什么是路由
2、路由的使用
3、获取请求报文参数
4、获取路由参数
5、路由参数练习
(四)express响应设置
(五)express 中间件
1、什么是中间件
2、中间件的作用
3、中间件的类型
3.1定义全局中间件
3.2多个全局中间件
3.3 定义路由中间件
全局中间件例子:(把中间件放在路由外面)
编辑
路由中间件实践(把路由中间件放在要受控制的函数里面)
4、静态资源中间件
5、获取请求体数据 body-parser
6、防盗链
(六)Router
1、什么是 Router
2、Router 作用
3、 Router 使用
(七)EJS 模板引擎
1、什么是模板引擎
2、什么是 EJS
3、EJS 初体验
4、EJS 常用语法
5、ejs列表渲染
6、ejs条件渲染(根据条件,输出需求)
7、express中使用ejs
8、express-generator工具
(八)express框架--查看文件上传报文
(九)express框架--处理文件上传
(十)案例:记账本
//1、导入express
const express = require('express');
//2、创建应用对象
const app =express();
//3、创建路由
app.get('/home',(req,res)=>{
res.end('hello,express');
});
//4、监听端口
app.listen(3000,()=>{
console.log('服务已启动...')
})
怎么样可以指定发送GET请求、post请求?
表单和ajax可以。
*号:后面接所有路由地址都行
一个路由的组成有 请求方法 , 路径 和 回调函数 组成
express 中提供了一系列方法,可以很方便的使用路由,使用格式如下:
app.(path,callback)
示例:
//导入 express
const express = require('express');
//创建应用对象
const app = express();
//创建 get 路由
app.get('/home', (req, res) => {
res.send('网站首页');
});
//首页路由
app.get('/', (req,res) => {
res.send('我才是真正的首页');
});
//创建 post 路由
app.post('/login', (req, res) => {
res.send('登录成功');
});
//匹配所有的请求方法
app.all('/search', (req, res) => {
res.send('1 秒钟为您找到相关结果约 100,000,000 个');
});
//自定义 404 路由
app.all("*", (req, res) => {
res.send('404 Not Found
')
});
//监听端口 启动服务
app.listen(3000, () =>{
console.log('服务已经启动, 端口监听为 3000');
});
//1、导入express
const express = require('express');
//2、创建应用对象
const app =express();
//3、创建路由
//获取报文的方式与原生 HTTP 获取方式是兼容的
app.get('/request',(req,res)=>{
//原生操作
console.log(req.method);
console.log(req.url)
console.log(req.httpVersion)
console.log(req.headers)
//experss操作 express 独有的获取报文的方式
console.log(req.path)
console.log(req.query)//获取查询字符串
console.log(req.ip) //获取ip
console.log(req.get('host'))//获取请求头
});
//4、监听端口
app.listen(3000,()=>{
console.log('服务已启动...')
})
什么是路由参数?
//1、导入express
const express = require('express');
//2、创建应用对象
const app =express();
//3、创建路由
//get方法
app.get('/:id.html',(req,res)=>{
//获取路由参数
console.log(req.params.id);
res.setHeader('content-type','text/html;charset=utf-8');
res.end('商品详情');
});
//4、监听端口
app.listen(3000,()=>{
console.log('服务已启动...')
})
说明:
根据路由参数获取歌手信息
路径结构如下:/singer/1.html
//获取请求的路由规则
app.get("/response", (req, res) => {
//1. express 中设置响应的方式兼容 HTTP 模块的方式
res.statusCode = 404;
res.statusMessage = 'xxx';
res.setHeader('abc','xyz');
res.write('响应体');
res.end('xxx');
//2. express 的响应方法
res.status(500); //设置响应状态码
res.set('xxx','yyy');//设置响应头
res.send('中文响应不乱码');//设置响应体
//连贯操作
res.status(404).set('xxx','yyy').send('你好朋友')
//3. 其他响应
res.redirect('http://atguigu.com')//重定向
res.download('./package.json');//下载响应
res.json();//响应 JSON
res.sendFile(__dirname + '/home.html') //响应文件内容
});
let recordMiddleware = function(request,response,next){
//实现功能代码
//.....
//执行next函数(当如果希望执行完中间件函数之后,仍然继续执行路由中的回调函数,必须调用next)
next();
}
应用中间件
app.use(recordMiddleware);
声明时可以直接将匿名函数传递给 use
app.use(function (request, response, next) {
console.log('定义第一个中间件');
next();
})
app.use(function (request, response, next) {
console.log('定义第一个中间件');
next();
})
app.use(function (request, response, next) {
console.log('定义第二个中间件');
next();
})
app.get('/路径',`中间件函数`,(request,response)=>{
});
app.get('/路径',`中间件函数1`,`中间件函数2`,(request,response)=>{
});
简单报错日志:
//导入模块
const express = require("express");
const fs = require('fs');
const path = require('path');
//创建应用对象
const app = express();
//声明中间件函数
function recordMiddleware(req,res,next){
//获取url和ip地址
let {url,ip}=req;
//将信息保存到 access.log文件中
fs.appendFileSync(path.resolve(__dirname+'/access.log'),`${url} ${ip}\r\n` )
//调用next
next()
}
//使用中间件函数
app.use(recordMiddleware);
//创建路由
app.get('/home',(req,res)=>{
res.send("前台页面")
});
app.get('/admin',(req,res)=>{
res.send("后台页面")
});
app.get('*',(req,res)=>{
res.send("404 not found")
})
//监听端口
app.listen(3000,()=>{
console.log('服务启动')
})
针对/admin /setting的请求,要求URL携带code= 521参数,如未携带提示【暗号错误】
//导入模块
const express = require("express");
//创建应用对象
const app = express();
//声明中间件函数
let checkCodeMiddleWare = (req,res,next)=>{
//判断URL中是否code参数等于521
if(req.query.code==='521'){
next();
}else{
res.send("暗号错误")
}
}
//创建路由
//前台
app.get('/home',checkCodeMiddleWare,(req,res)=>{
res.send("前台页面")
});
//后台
app.get('/admin',checkCodeMiddleWare,(req,res)=>{
res.send("后台页面")
});
//后台设置页面
app.get('/setting',(req,res)=>{
res.send("设置页面")
})
app.all('*',(req,res)=>{
res.send("404 not found")
})
//监听端口
app.listen(3000,()=>{
console.log('服务启动')
})
express 内置处理静态资源的中间件
//引入express框架
const express = require('express');
//创建服务对象
const app = express();
//静态资源中间件的设置,将当前文件夹下的public目录作为网站的根目录
app.use(express.static('./public')); //当然这个目录中都是一些静态资源
//如果访问的内容经常变化,还是需要设置路由
//但是,在这里有一个问题,如果public目录下有index.html文件,单独也有index.html的路由,
//则谁书写在前,优先执行谁
app.get('/index.html',(request,response)=>{
respsonse.send('首页');
});
//监听端口
app.listen(3000,()=>{
console.log('3000 端口启动....');
});
npm i body-parser
const bodyParser = require('body-parser');
//处理 querystring 格式的请求体
let urlParser = bodyParser.urlencoded({extended:false}));
//处理 JSON 格式的请求体
let jsonParser = bodyParser.json();
app.post('/login', urlParser, (request,response)=>{
//获取请求体数据
//console.log(request.body);
//用户名
console.log(request.body.username);
//密码
console.log(request.body.userpass);
response.send('获取请求体数据');
});
[Object: null prototype] { username: 'admin', userpass: '123456' }
//导入模块
const express = require('express');
const bodyParser = require('body-parser');
//创建应用对象
const app = express();
//处理 querystring 格式的请求体
let urlParser = bodyParser.urlencoded({extended:false});
//处理 JSON 格式的请求体
// let jsonParser = bodyParser.json();
//创建路由
//get规则
app.get('/login',(req,res)=>{
//响应HTML文件
res.sendFile(__dirname+'/form.html')
})
//post规则
app.post('/login',urlParser,(req,res)=>{ //当urlParser中间件函数执行完毕后,会往请求对象(request)身上添加一个属性,名字叫body
//获取用户请求体和密码
res.send('获取数据')
console.log(req.body)
})
//监听端口
app.listen(3000,()=>{
console.log("服务启动")
})
只能在限制域名内访问,超出则不会响应。
关键点:referer请求头
案例:要是访问地址不是127.0.0.1就不会显示图片。
//导入模块
const express = require("express");
//创建应用对象
const app = express();
//声明中间件
app.use((req,res,next)=>{
//检测请求头中的referer 是否为127.0.0.1
//获取referer
let referer = req.get('referer');
if(referer){
//实例化
let url = new URL(referer);
//获取hostname
let hostname = url.hostname
console.log(hostname)
//判断
if(hostname!='127.0.0.1'){
//响应404
res.status(404).send('404 not found
');
return;
}
}
next();
})
//静态资源中间件设置
app.use(express.static(__dirname+'/public')) //这个路径就是静态文件夹的路径
//监听端口
app.listen(3000,()=>{
console.log('服务启动')
})
//1. 导入 express
const express = require('express');
//2. 创建路由器对象
const router = express.Router();
//3. 在 router 对象身上添加路由
router.get('/', (req, res) => {
res.send('首页');
})
router.get('/cart', (req, res) => {
res.send('购物车');
});
//4. 暴露
module.exports = router;
const express = require('express');
const app = express();
//5.引入子路由文件
const homeRouter = require('./routes/homeRouter');
//6.设置和使用中间件
app.use(homeRouter);
app.listen(3000,()=>{
console.log('3000 端口启动....');
})
npm i ejs --save
//1.引入ejs
const ejs = require('ejs');
//2.定义数据
let person = ['张三','李四','王二麻子'];
//3.ejs解析模板返回结构
//<%= %> 是ejs解析内容的标记,作用是输出当前表达式的执行结构
let html = ejs.render(‘<%= person.join(",") %>’, {person:person});
//4.输出结果
console.log(html);
自己写的案例:
js页面:
//1、安装EJS
//2、导入EJS
const ejs = require('ejs');
const fs=require('fs');
//字符串
let china="中国";
let weather='今天天气不错';
//声明变量
let str = fs.readFileSync('01.html').toString();
//让ejs渲染
let result = ejs.render(str,{china,china,weather});
console.log(result);
html页面:
我爱你 <%= china%>
<%= weather%>
<% code %>
<%= code %>
<%- code %>
js页面:
//导入模块
const ejs = require('ejs');
const fs=require('fs');
const xiyou =["唐僧","孙悟空","猪八戒","沙僧"];
let html = fs.readFileSync('./02.html').toString();
let result = ejs.render(html,{xiyou:xiyou});
console.log(result);
html:
西游F4
西游四人组
<% xiyou.forEach(item=>{%>
- <%=item%>
<% }) %>
通过 isLogin 决定最终的输出内容
true 输出 [欢迎回来]
false 输出 [ ]
//导入模块
const ejs=require('ejs');
const fs = require('fs')
//变量
let isLogin=true;
//获取html
let html = fs.readFileSync('./03_条件渲染.html').toString();
let result=ejs.render(html,{Login:isLogin});
console.log(result);
西游F4
<% if(Login){%>
欢迎回来
<%}else{%>
<%}%>
先创建一个文件夹views
在创建一个文件:home.ejs用来写模板引擎文件。
//导入express
const express =require('express');
const path = require('path');
//创建应用对象
const app = express();
//1、设置模板引擎
app.set('view engine','ejs');//模板引擎pug twing
//2、设置模板文件存放的位置 模板文件:具有模板语法内容的文件
app.set('views',path.resolve(__dirname,'./views'));
//创建路由
app.get('/home',(req,res)=>{
//3、render响应
// res.render('模板文件名','数据')
//声明变量
let title = '尚硅谷-让天下没有难学的技术';
res.render('home',{title});
//创建模板文件
});
//监听端口,启动服务
app.listen(3000,()=>{
console.log('服务已启动。。。')
})
html:home.ejs
<%=title%>
文件结构:
通过应用生成器工具express-generator 可以快速创建一个应用的骨架
全局安装
npm install -g express-generator
查看
express
快速创建文件夹(-e是安装ejs的模板引擎,后面跟着你要创建文件夹的名字)
express -e 06_generator
进入刚创建的文件,安装依赖
npm i
运行一下
npm start
打开127.0.0.1:3000
在 package.json文件修改
准备工作:
先在上一题新建的06_generator文件夹里新建一个views文件夹
然后在建一个portrait.ejs
js文件
var express = require('express');
var router = express.Router();
//显示网页的(表单)
router.get('/portrait',(req,res)=>{
res.render('portrait');
});
//处理文件上传
router.post('/portrait',(req,res)=>{
res.send('成功')
})
module.exports = router;
要是新建了路由文件,一定要在app.js文件里配置路由。
运行:
准备工作:
安装 formidable
npm i formidable
var express = require('express');
var router = express.Router();
const formidable = require('formidable');
const path=require('path');
//显示网页的(表单)
router.get('/portrait',(req,res)=>{
res.render('portrait');
});
//处理文件上传
router.post('/portrait',(req,res,next)=>{
//创建form对象
const form = formidable({ multiples: true ,
//设置文件上传的保存目录
uploadDir:path.resolve(__dirname,'../public/images'),
//保持文件后缀
keepExtensions:true
});
//请求解析报文
form.parse(req, (err, fields, files) => {
if (err) {
next(err);
return;
}
console.log(fields)//text radio checkbox select
//图片的URL保存在了files里的newFilename。
console.log(files)//file
// res.json({ fields, files });
//服务器保存该图片的访问URL
let url = '/images/'+files.portrait.newFilename;//将来将此数据保存在数据库中。
res.send(url)
});
})
module.exports = router;
portrait.ejs
运行:
准备工作:
express -e accounts
npm i
lowdb:(建议下载1.0.0版本,不用ES6语法)了解即可
Simple to use local JSON database. Use native JavaScript API to query. Written in TypeScript.
易于使用的本地JSON数据库。使用本机JavaScript API进行查询。用TypeScript编写。
在项目里新建一个文件夹test
在先建一个lowdb.js
控制台进入test文件夹
cd test
安装
npm i [email protected]
使用方法:
//导入lowdb
const low = require('lowdb')
const FileSync = require('lowdb/adapters/FileSync')
const adapter = new FileSync('db.json')
//获取db对象
const db = low(adapter)
//初始化数据
db.defaults({ posts: [], user: {} })
.write()
//写入数据
db.get('posts')
.push({ id: 1, title: 'lowdb is awesome'})
.write()
//获取单条数据
db. get('posts').find({id:1}).value();
//获取数据
console.log(db.get('posts').value());
//删除数据
let res=db.get('posts').remove({id:1}).write();
console.log(res)
//更新数据
db. get('posts').find({id:1}).assign({title:'今天下雨啦'}).write();
shortid:自动添加id名
npm i shortid
详细见项目代码--案例_记账本