Express框架

Posted 煜成'Studio

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Express框架相关的知识,希望对你有一定的参考价值。


title: Express框架
date: 2022-01-16 09:51:18
tags:


Express框架

express是一个基于内置核心http模块的一个第三方的包,专注于web服务器的构建。

//在项目文件夹express路径cmd之后,
//初始化项目
yarn init -y
//安装express
yarn add express

使用express搭建一个简单的服务器

app.js

//1.引入express
const express = require("express");
//2.创建app对象(项目对象),它就是项目最大的这个对象
const app = express();
//4.处理请求,第一个参数是请求路径,第二个参数是针对这个路径的处理函数
app.get("/", (req, res) => 
    //这个函数有两个形参
    //第一个形参req是请求对象(跟请求相关的数据需要用它)
    //第二个形参res是响应对象(跟响应相关的工作需要用它)
    
    //响应一个字符串给浏览器
    res.send("hello express 框架!");
)

//3.监听是否有请求
app.listen(3000, () =>  //3000是端口号
    //这里的代码会在服务器启动的时候执行一次
    console.log("Express web server is listening at 3000 port!");
)

处理get请求

const express = require("express");
const fs = require("fs");
const path = require("path");

const app = express();

app.get("/", (req, res) => 
    console.log("首页的内容");
    res.send("首页"))

app.get("/register", (req, res) => 
    //获取文件路径
    let filePath = path.join(__dirname, "views", "register.html"); //登录页面的路径
    //读取文件内容
    let content = fs.readFileSync(filePath, "utf-8");
    res.send(content);
)

app.listen(3000, () => 
    console.log("Express web server is listening at 3000 port!");
)

获取get请求的参数

const express = require("express");

const app = express();

app.get("/index", (req, res) =>  
    //请求地址假如为/index?name=express&age=11,也可以匹配到,自动搜索?前的内容
    //req.query是获取到的字符串参数,是一个对象,name: 'express', age: '11'
    console.log(req.query.name);
    res.send("index首页");
)

app.get("/list", (req, res) => 
    //地址为/list?curPage=1&perPage=10&catagoryId=2
    res.send(req.query.curPage);
)

app.listen(3000, () => 
    console.log("Express web server is listening at 3000 port!");
)

处理post请求

//客户端
<form method="POST" action="/register"> 
    //不添加enctype="application/x-www-form-urlencoded"也行,默认已经有了
    //作用是将表单里的数据编程username=express&age=11这种形式
    ...
</form>

//服务端
const express = require("express");

const app = express();

app.get("/index", (req, res) =>  
    console.log(req.query.name);
    res.send("index首页");
)

app.get("/list", (req, res) => 
    res.send(req.query.curPage);
)

//get请求是在页面地址栏进行请求,post是在表单提交的时候进行请求
app.post("/register", (req, res) => 
    //可以在这个接口中处理post请求
    
    res.send("post ok");
)

app.listen(3000, () => 
    console.log("Express web server is listening at 3000 port!");
)

获取post请求参数

使用第三方的包body-parser更加简便专业地处理请求参数

需要在项目目录下安装body-parser(在安装express的时候已经安装了,node_mudules文件夹下可以看到)

yarn add body-parser 或者 npm install body-parser
//客户端
<form method="POST" action="/register"> 
    //不添加enctype="application/x-www-form-urlencoded"也行,默认已经有了
    //作用是将表单里的数据编程username=express&age=11这种形式
    ...
</form>


//服务端
const express = require("express");
const fs = require("fs");
const path = require("path");
//1.引入body-parser
const bodyParser = require("body-parser");

const app = express();

//2.把bodyParser添加到项目中,把bodyParser注册到app下(使它能在app项目中使用)
app.use(bodyParser.urlencoded(extended: false)); //false接收的值为字符串或者数组,true则为任意类型
app.use(bodyParser.json()); //将来获取之后解析为json格式


app.get("/", (req, res) => 
    console.log("首页的内容");
    res.send("首页"))

app.get("/register", (req, res) => 
    let filePath = path.join(__dirname, "views", "register.html"); //登录页面的路径
    let content = fs.readFileSync(filePath, "utf-8");
    res.send(content);
)

app.post("/register", (req, res) => 
    //可以在这个接口中处理post请求,一般post提交过来后,后端需要获取提交过来的参数
    //获取用户填写的数据,也叫请求参数
    
    //3.获取参数,用req.body来获取,是一个对象
    let username, email, password, repwd = req.body; //解构
    console.log(username, email, password, repwd); //在服务端的小黑框里展示
    
    //业务逻辑
    //校验参数是不是符合规则,判空
    //查询数据库,看看用户名是否被注册等等业务逻辑
    
    res.send("post ok");
)

app.listen(3000, () => 
    console.log("Express web server is listening at 3000 port!");
)

重定向

const express = require("express");
const fs = require("fs");
const path = require("path");
const bodyParser = require("body-parser");

const app = express();

app.use(bodyParser.urlencoded(extended: false)); 
app.use(bodyParser.json());

app.get("/", (req, res) => 
    res.send("首页"))

app.get("/register", (req, res) => 
    let filePath = path.join(__dirname, "views", "register.html");
    let content = fs.readFileSync(filePath, "utf-8");
    res.send(content);
)

//登录页面,表单post提交之后跳转到该页面
app.get("/login", (req, res) => 
    let filePath = path.join(__dirname, "views", "login.html");
    let content = fs.readFileSync(filePath, "utf-8");
    res.send(content);
)

app.post("/register", (req, res) => 
    let username, email, password, repwd = req.body;
    console.log(username, email, password, repwd);
    //不想返回这个"post ok",表单注册完提交之后跳转到login.html页面
    //res.send("post ok");
    //重定向
    //res.writeHead(302); //修改响应头中的状态码
    //res.writeHead(302, name: "nodejs"); //添加一个响应头的键值对
    //没有上面的两行代码,重定向后在开发者工具中的状态码也为302
    //上面的代码不注释的话会报错,Cannot set headers after they are sent to the Client
    //意思是已经返回给浏览器了还去设置响应头
    res.redirect("/login"); 
    //本来是在这里运动代码,现在调到app.get("/login", (req, res) => ...)这个login接口里执行代码了
)

app.listen(3000, () => 
    console.log("Express web server is listening at 3000 port!");
)

all方法合并相同的路径请求

//如果请求路径相同,可以用all方法合并//将下面两个合并app.get("/register", (req, res) =>     let filePath = path.join(__dirname, "views", "register.html");    let content = fs.readFileSync(filePath, "utf-8");    res.send(content);)app.post("/register", (req, res) =>     let username, email, password, repwd = req.body;    console.log(username, email, password, repwd);    res.redirect("/login"); )//all方法app.all("/register", (req, res) =>     //先获取请求方式req.method,根据请求方式执行对应的代码处理    if(req.method === "GET")         let filePath = path.join(__dirname, "views", "register.html");    	let content = fs.readFileSync(filePath, "utf-8");    	res.send(content);     else if(req.method === "POST")         let username, email, password, repwd = req.body;    	console.log(username, email, password, repwd);    	res.redirect("/login");     )

获取静态资源的方式

const express = require("express");const app = express();//一个项目一般都会有一个静态资源文件夹//现在图片放在public文件夹下的image文件夹下//设置在public文件夹下查找资源(以public为根去找静态资源),地址栏的/就是根的意思,//http://127.0.0.1:3000/images/01.jpg,根下的images文件夹下的jpg图片app.use(express.static("public"));//在html文件中<img src="/images/01.jpg" alt="" />地址这样写就可以获取到图片了//在静态资源的路径下加一个前缀,却不想在public文件夹和images文件夹中再新建一个文件夹,可以设置第一个参数//app.use("/static", express.static("public"));//此时的地址为http://127.0.0.1:3000/static/images/01.jpgapp.get("/", (req, res) =>     res.send("hello express");)app.listen(3000, () =>     console.log("Express web server is listening at 3000 port!");)

art-template模板引擎的使用

使用前需要安装art-tamplate和express-art-template

yarn add art-template 或者 npm install art-templateyarn add express-art-template 或者 npm install express-art-template

在views目录下新建index.html

读取这个文件,但是不使用之前的读取路径的方法,使用art-template

const express = require("express");const path = require("path");const app = express();//下面的四句代码是模板引擎的初始化工作//引入express-art-template,使用对应引擎,原版本第一个参数是art,因为我们这里需要使用index.html,所以直接就换了,第四句代码中也是如此app.engine('html', require('express-art-template'));//项目环境的设置//生产环境(线上)production//开发环境developmentapp.set('view options',     debug: process.env.NODE_ENV !== 'production');//设置在哪一个目录下查找模板文件(html文件)app.set('views', path.join(__dirname, 'views')); //当前路径的views文件夹下//和第一句一样需要设置模板的后缀名为htmlapp.set('view engine', 'html');app.get("/", (req, res) =>     //这里就不需要引入之前的那种路径读取文件的方式了,直接这么写    //res.render是模板引擎    res.render("index"); //返回index页面给浏览器,注意这里不需要有.html后缀名,上面已经设置了)app.listen(3000, () =>     console.log("Express web server is listening at 3000 port!");)

art-template模板引擎传递数据

const express = require("express");const path = require("path");const app = express();app.engine('html', require('express-art-template'));app.set('view options',     debug: process.env.NODE_ENV !== 'production');app.set('views', path.join(__dirname, 'views'));app.set('view engine', 'html');app.get("/", (req, res) =>     //我们可以在接口("/"这种路径)中查询数据库,得到数据之后传递给模板展示在页面上    //现在假如给了一些数据    let data =         num1: 10,        num2: 5        user:         	name: zhangsan,        	age: 11    	,        books: ["haha", "lala"]        res.render("index", data); //返回index页面给浏览器并把data传递到模板中,在index.html中就可以使用这些数据了,例如<p> num1 </P>,就可以在页面上直接显示10了,这里用到了插值表达式,这个插值表达式的模板不是vue,而是art-template,之前装的art-template就是解析页面中例如插值表达式这些模板的,express-art-template则是在express中使用的目的    //在页面中还有很多语法,例如 num1 > num2 ? num1 : num2 	// user.age , user["age"] 	//数组的话需要把数组的每一项都放在li标签中,用each	//<ul>    //    each books //用each,books为数组名    //    	<li> $index   $value </li> //$index是下标,$value是每一项的值	//	/each //还需要一个结束符    //</ul>	//如果num1小于num2就展示下面这个p标签,否则就不展示,用if,节点移除了,找不到了,和vue的v-if是一样的	//if num1 > num2	//	<p>num1是小于num2的</p>	///if	//如果把上面改为num1 < num2发现在编辑器里颜色不对,不是语法问题能正常编译,知识编辑器不支持这种语法格式	//还有很多语法)app.listen(3000, () =>     console.log("Express web server is listening at 3000 port!");)

art-template模板过滤器的使用

const express = require("express");//1.引入art-templateconst template = require("art-template");const path = require("path");const app = express();app.engine('html', require('express-art-template'));app.set('view options',     debug: process.env.NODE_ENV !== 'production');app.set('views', path.join(__dirname, 'views'));app.set('view engine', 'html');//2.书写过滤器函数//template.defaults.imports.过滤器名称 = function(value) //    return 返回出过滤后的数据;//template.defaults.imports.timestamp = function(value)     //value是|前面的数据,这里也就是num1    return value * 1000; //返回出过滤后的数据//3.在模板中使用过滤器函数 数据 | 过滤器名称 app.get("/", (req, res) =>     let data =         num1: 10,        res.render("index", data);        //在html文件的过滤器形式是 num1 | timestamp        //注意在html文件中不要再注释里面写,因为即使是注释里,编译器也会认为这里需要解析)app.listen(3000, () =>     console.log("Express web server is listening at 3000 port!");)

在项目中使用路由

入口文件app.js应保持整洁,需要的接口应该放在routes路由文件夹下,文件夹下有passport.js(根验证相关的代码放在这里处理)。没有了app对象,就用express.router()

passport.js

const express = require("express");const fs = require("fs");const path = require("path");const router = express.router();router.get("/register", (req, res) =>     let filePath = path.join(__dirname, "../views", "register.html"); //地址变了    let content = fs.readFileSync(filePath, "utf-8");    res.send(content);)router.get("/login", (req, res) =>     let filePath = path.join(__dirname, "../views", "login.html"); //地址变了    let content = fs.readFileSync(filePath, "utf-8");    res.send(content);)router.post("/register", (req, res) =>     let username, email, password, repwd = req.body;    console.log(username, email, password, repwd);    res.redirect("/login"); )//导出module.exports = router;

index.js

const express = require("express");const router = express.router();router.get("/", (req, res) =>     console.log("首页的内容");    res.send("首页"))module.exports = router;

app.js

const express = require("express");const bodyParser = require("body-parser");//引入passport里的路由const passportRouter = require("./routes/passport");const indexRouter = require("./routes/index")const app = express();app.use(bodyParser.urlencoded(extended: false)); app.use(bodyParser.json());//把路由注册到app下app.use(passportRouter);app.use(indexRouter);app.listen(3000, () =>     console.log("Express web server is listening at 3000 port!");)

处理请求之前的钩子函数

const express = require("express");const bodyParser = require("body-parser");const passportRouter = require("./routes/passport");const app = express();app.use(bodyParser.urlencoded(extended: false)); app.use(bodyParser.json());//这种钩子函数的作用是,网站有些功能需要登陆之后才能使用,比如收藏、关注等,可以在这里校验是否登录,//没有登录的话必须组织继续往下执行//这种函数党政一个校验是否登录的工具,也不会放在入口文档中function checkLogin(req, res, next) 	console.log("执行passportRouter的路由接口函数之前先执行这句代码");		//这里假设true是没有登录,则return直接跳出该函数,不会执行next()了	//if(true) 	//	res.send("登录校验没有通过");	//	return;	//		next(); //跳转的作用。去执行app.use后面的这个函数里面的代码,在这里也就是passportRouter函数//第一个参数要是checkLoginapp.use(checkLogin, passportRouter); //在执行passport.js里面的函数之前就会执行checkLogin这个函数的代码app.listen(3000, () =>     console.log("Express web server is listening at 3000 port!");)

创建一个utils文件夹,专门放置工具函数

utils文件夹下创建index.js文件

function checkLogin(req, res, next) 	console.log("执行passportRouter的路由接口函数之前先执行这句代码");	next();//其他函数//...//因为还有其他函数,所以以对象的形式导出module.exports =     checkLogin

app.js

const express = require("express");const bodyParser = require("body-parser");const passportRouter = require("./routes/passport");const utils = require("./utils"); //如果导入的是index.js文件,路径简写到utils就可以const app = express();app.use(bodyParser.urlencoded(extended: false)); app.use(bodyParser.json());app.use(utils.checkLogin, passportRouter);app.listen(3000, () =>     console.log("Express web server is listening at 3000 port!");)

pathinfo/pathname参数的获取

const express = require("express");const path = require("path");const app = express();app.engine('html', require('express-art-template'));app.set('view options',     debug: process.env.NODE_ENV !== 'production');app.set('views', path.join(__dirname, 'views'));app.set('view engine', 'html');app.get("/list", (req, res) =>     res.render("list");)app.get("/detail/:id", (req, res) =>     //不同的地址的内容不一样	//:id表示动态地获取detail/后面的内容,这个参数叫做pathinfo/pathname参数    //通过req.params获取参数对象,加入点击页面新闻标题1,则拿到id: '1',req.params.id可以获取1    //再根据这个id去查询数据库,获取这篇文章的内容,传到模板里面去    res.send("detail详情页" + req.params.id);)//假如地址是这样的<li><a href="/detail/1/music">新闻标题1</a></li>//可以这样app.get("/detail/:id/:type", (req, res) => ...),//相当于req.params这个对象多了一个键值对id: '1', type: 'music'app.listen(3000, () =>     console.log("Express web server is listening at 3000 port!");)

list.html

<ul>    <li><以上是关于Express框架的主要内容,如果未能解决你的问题,请参考以下文章

express框架

对于express框架的基本理解

Express框架请求与响应Express页面

express框架的基本使用

Express框架概述

Express框架