目录
一. express框架
1. Express 简介
2. 创建web服务器
3. 创建路由
⬛ res 响应的对象
⬛ req 请求的对象
对比get和post两种请求方法
路由传参
二. 路由器
1. 给路由添加前缀
2. 路由器的使用
◼️ 创建路由器
◼️ 在web服务器下引入并挂载
【前文回顾】 Nodejs常见全局对象之模块对象全解析_02
Express是目前最流行的基于Node.js的Web应用开发框架,可以快速地搭建一个完整功能的网站。
Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种
Web 应用,和丰富的 HTTP 工具。
使用 Express 可以快速地搭建一个完整功能的网站。
Express 框架核心特性:
可以设置中间件来响应 HTTP 请求。
定义了路由表用于执行不同的 HTTP 请求动作。
可以通过向模板传递参数来动态渲染 HTML 页面。
框架有一整套解决方案
Express 中文网:https://www.expressjs.com.cn/
express是基于Nodejs平台,快速,开放,极简的web开发框架
下载安装 npm install express
//引入express包
const express=require('express');
//创建web服务器
const app=express();
//设置端口
app.listen(8080);
用来处理特定的请求(如登录的路由、注册的路由等等),包含有请求的方法、请求的URL、回调函数。
️ 闲话:关于浏览器的请求
之前我们是利用在服务器下添加事件的方式处理浏览器向服务器发出的请求,事件里面写了很多操作包括处理一个商品列表、一个首页以及一个响应文件、一个跳转、一个404等的多种操作,一个事件中做了太多的事情,显得非常的乱,所以各个操作应该分开处理,可以使用不同的路由处理不同的请求操作,比如请求列表的,就是写一个列表路由,这就相当于餐厅的服务员,中餐服务员负责中餐,西餐由西餐服务员来负责,各司其职
只有请求的方法和请求的URL同时匹配,才会执行回调函数
res.send() 设置响应的内容并发送
res.sendFile() 设置响应的文件并发送,文件需要使用绝对路径 __dirname
res.redirect() 设置响应的重定向,跳转到另一个URL
req.method 获取请求的方法
req.url 获取请求的URL
req.query 获取查询字符串传递的数据,格式化为对象
练习:创建路由
创建首页的路由(/index,get),响应
//引入express包
const express = require('express');
//console.log(express);
//创建web服务器
const app = express();
//设置端口
app.listen(8080);
//处理商品列表的路由
//请求的URL:/list,请求的方法:get
//通过回调函数作出响应
app.get('/list', (req, res) => {
//req 请求的对象
//res 响应的对象
/*
*当前端浏览器发出请求,后端代码自动执行回调函数,通过回调函数响应
*也就是说启动服务器后,浏览器发出请求,在命令行窗口(后端)可以查看到服务器作出的响应是浏览器
*发出的请求url和请求方法/list GET
*console.log只能在控制台跟命令行输出
*console.log(req.url,req.method);
*/
//设置响应的内容并发送
res.send('这是商品列表');
});
//练习:创建首页的路由(/index, get),响应 这是首页
app.get('/index', (req, res) => {
res.send('这是首页
');
});
//请求的URL: / 请求的方法: get ,响应文件1.html
app.get('/', (req, res) => {
//响应文件
res.sendFile(__dirname + '/1.html');
});
//当前模块的绝对目录
//console.log(__dirname);
//商品详情路由
//请求方法: get 请求URL: /detail
app.get('/detail', (req, res) => {
res.sendFile(__dirname + '/detail.html');
});
//跳转
//请求的方法: get 请求的URL: /study
app.get('/study', (req, res) => {
res.redirect('https://www.expressjs.com.cn/');
});
扩展:关于res.redirect() 的执行过程:
浏览器发出请求:http://127.0.0.1:8080/study 重定向到指定的网址Express 中文网在重定向的页面,打开浏览器控制台,点击请求的study路由,可以知晓浏览器自动为study设置302状态码
如下图:整个跳转是由status 302和Location共同完成的,express在内部封装了res.redirect()方法,而不用再设置响应头 res.writeHead(302,{
Location:'https://www.expressjs.com.cn/'
get请求传递的数据以查询字符串传递,可能被浏览器所缓存,速度相对块,传递数据不超过4K。(get方法传递的是数据,不能传递文件)
post传递的数据以请求主体的的方式传递,不被浏览器所缓存,速度相对慢,可以传递大文件
释义:关于Payload的含义
Payload英语单词意思是有效载荷,在http中,应该是post请求时,所携带的有效数据的意思。
比如你post请求上传文件,用谷歌浏览器抓包可以看到payload相关信息,它分成了多组数据描述信息,用类似于“------WebKitFormBoundaryaL7XJASi3bOcnKjn”这样的字符串分割。
Content-Disposition: form-data; name="localUrl"这个是描述上传的文件的本地路径,Content-Disposition: form-data; name="imgFile"; filename="1.png" Content-Type: image/png这个是描述上传的图片的mime类型
传递方式 | 格式 | 获取 |
---|---|---|
get传递 | 查询字符串 | req.query 格式为对象 |
post传递 | 流(不可见) | 通过事件获取 req.on('data',(chunk)=>{ //chunk是分段的数据,格式化为buffer,需要转字符串,转完后为查询字符串,需要解析为对象 }) |
路由传参(动态路由) | 通过URL | req.params 格式化为对象 |
注:req.query与req.params
req.query后获取的是url中问号后面的数据 ------用于get请求当中
req.params后获取的是url中斜杠后面的数据 ------用于get请求当中
◾ 如何使用
app.get('/package/:pname',(req,res)=>){
//:pname 设置形参名称 (用于获取、保存用户传来的实参)
req.params 获取路由传参的数据,格式化为对象
});
◾ 如何传递
http://127.0.0.1:8080/package/express
注:express就是传递的数据,也就是实参
练习:编写文件03_express.js,使用express创建web服务器,设置端口8080,添加路由(get /search),响应文件search.html;点击提交,再次向服务器发请求(post,/mysearch),创建对应的路由,响应"这是商品列表"
练习:创建路由(get /login),响应登录的文件login.html;点击提交,再次向服务器发请求(post,/mylogin),创建对应的路由,响应"登录成功"
练习:创建添加到购物车的路由(get /shopping),使用路由传参传递商品的编号lid和数量num,在路由获取数据;
*03_express.js
//引入express包
const express = require('express');
//引入查询字符串模块
const querystring = require('querystring');
//创建web服务器
const app = express();
//设置端口
app.listen(8080);
//响应搜索网页的路由
//get /search
app.get('/search', (req, res) => {
res.sendFile(__dirname + '/search.html');
});
//根据表单提交请求创建对应的路由
//get /mysearch
app.get('/mysearch', (req, res) => {
//req 请求对象
// console.log(req.method,req.url);
//直接获取到传递的数据,格式为对象
/*
*在express框架中,提供了req.query()方法,因此,不再需要引入url模块将浏览器地址栏的URL解析为对象即:
*let obj=url.parse(str);
*然后再获取查询字符串部分即:
*obj.query;
*而是使用exress框架中提供的req.query()方法,直接获取到传递的数据,并且格式为对象
*/
console.log(req.query);
res.send('这是商品列表:' + req.query.keyword);
});
//路由,获取登录的网页
//get /login
//在下一篇文章中,我们可以通过托管静态资源代替通过路由找寻文件:当浏览器端请求文件,不需要通过路由去寻找文件,而是让浏览器自动到指定的目录下去寻找。
app.get('/login', (req, res) => {
res.sendFile(__dirname + '/login.html');
});
//根据表单的请求创建对应的路由
//post /mylogin
app.post('/mylogin', (req, res) => {
//获取post传递的数据
//以流的形式传递,通过事件
//一旦有数据流入,自动调用回调函数
req.on('data', (chunk) => {
//将分段的数据放入到参数chunk,格式为buffer
//console.log(chunk);
//转字符串为查询字符串
let str = String(chunk);
//console.log(str);
//解析为对象
let obj = querystring.parse(str);
console.log(obj);
/*
*由于req.on事件是个异步操作的任务,因此不会阻止下方代码的执行,
*所以,如果想要显示res.send('登录成功,欢迎:'+obj.uname)中的obj.uname必须放进事件回调函数里
*等on事件之后的代码执行完,最后执行on事件的回调函数后,紧接着执行res.send('登录成功,欢迎:'+obj.uname)
*但是如果只是响应res.send('登录成功')的提示,就可以放在on事件外面
*/
res.send('登录成功,欢迎:' + obj.uname);
})
});
//路由:查看包的使用详情
//get /package
app.get('/package/:pname', (req, res) => {
//获取路由传参的数据,格式为对象
console.log(req.params);
res.send('这是包的使用详情');
});
// 练习:创建添加到购物车的路由(get /shopping),使用路由传参传递商品的编号lid和数量num,在路由获取数据
app.get('/shopping/:lid/:num', (req, res) => {
console.log(req.params);
res.send('购物车添加成功');
});
项目开发中,可能出现不同模块下相同的URL,造成URL冲突,为了团队协作,独立出每个功能模块,使用路由器将当前模块下所有的路由放到一起,并给URL添加前缀,最后挂载到web服务器下
商品模块 添加前缀/product
/product/list /product/delete
用户模块 添加前缀/user
/user/list /user/delete
注:关于路由器模块
路由器模块是用户自定义的模块,所以引入服务器时,采用的是模块分类中文件模块的用户自定义模块的引入方法,如引入路由器:const userRouter=require('./user.js');
/* 创建路由器 ------用户路由器user.js */
//引入express包
const express=require('express');
//创建路由器对象
const r=express.Router();
//往路由器中添加路由
r.get('/list',(req,res)=>{
res.send('这是用户列表');
});
//导出路由器对象
module.exports=r;
/* 在web服务器下引入并挂载 ------服务器app.js */
//引入express包
const express=require('express');
//创建web服务器
const app=express();
//设置端口
app.listen(8080);
//引入用户路由器
const userRouter=require('./user.js');
//挂载路由器到web服务器下,添加前缀
//参数1:添加的前缀 /user 访问形式 /user/list
//参数2:要挂载的路由器
app.use('/user',userRouter);
练习:创建商品路由器product.js,添加商品列表路由(get /list),导出路由器,在web服务器下引入并挂载,添加前缀 /product
*商品路由器product.js
//引入express包
const express=require('express');
//创建路由器对象
const r=express.Router();
//往路由器中添加路由
//商品列表路由:get /list
r.get('/list',(req,res)=>{
res.send('这是商品列表');
});
//导出路由器对象
module.exports=r;
*web服务器app.js
//引入express包
const express=require('express');
//引入路由器模块
const productRouter=require('./product.js');
//console.log(productRouter);
//创建web服务器
const app=express();
//设置端口
app.listen(8080);
//在web服务器下挂载,同时添加前缀 /product
app.use('/product',productRouter);
️ 扩展:请求对象与响应对象
◾ 请求对象后端服务器请求的对象(req)获取前端用户传递数据的三种方式(请求方法):
①req.query:获取以查询字符串传递的数据(query来接收)
②req.params:获取以路由传参传递的数据(params来接收)
③req.on (‘data’,(chunk)=>{}) :以req.on事件传递,这个方式是使用post的请求方法传递:req.on(‘data’,(chunk)=>{chunk分段数据,格式为buffer对象 })
◾ 响应的对象:
①res.send()
②res.sendFile()
③res.redirect()
【后文传送门】深入理解Express框架之如何使用各类中间件_04
如果这篇【文章】有帮助到你,希望可以给【青春木鱼】点个赞,创作不易,相比官方的陈述,我更喜欢用【通俗易懂】的文笔去讲解每一个知识点,如果有对【前端技术】感兴趣的小可爱,也欢迎关注❤️❤️❤️【青春木鱼】❤️❤️❤️,我将会给你带来巨大的【收获与惊喜】!