一、Express框架

express是一个基于Noed.js平台的极简、灵活的WEB应用开发框架,官方网址:https://www.expressjs.com.cn/ 简单来说,express是一个封装好的工具包,封装了很多功能,便于我们开发WEB应用(HTTP服务)

二、express使用
2.1、express下载

express本身是一个npm包,所以可以通过npm安装

npm init
npm i express
2.2、express初体验

1、创建JS文件,键入如下代码

// 1 导入express
const express = require("express");

// 2 创建应用对象
const app = express();

// 3 创建路由
app.get("/home", (req, res) => {
  res.send("hello express");
});

// 4 监听端口,启动服务
app.listen(3000,()=>{
    console.log('服务启动,端口3000')
})

2、命令行下执行该脚本文件

三、express路由
3.1什么是路由

官方定义:路由确定了应用程序如何响应客户端对特定端点的请求

3.2路由的使用

一个路由的组成有请求方法,路径和回调函数组成

express中提供了一系列的方法,可以很方便的使用路由,使用格式如下

app.<method>(path,callback)

代码演示:

// 导入express
const express = require("express");

// 创建应用对象
const app = express();

// 创建路由
app.get("/home", (req, res) => {
  res.end("hello express");
});

app.get("/", (req, res) => {
  res.end("home");
});

app.post("/login", (req, res) => {
  res.end("login");
});

app.all("/test", (req, res) => {
  res.end("test");
});

app.all("*", (req, res) => {
  res.send("404 not Found");
});

// 监听端口,启动服务
app.listen(3000, () => {
  console.log("服务启动,端口3000");
});

3.3获取请求报文参数

express框架封装了一些API来方便获取请求报文中的数据,并且兼容原生HTTP模块的方式获取

const express = require('express')

const app = express()
// 获取请求的路由规则
app.get('/request',(req,res)=>{
    // 1 获取报文的方式与原生 HTTP获取方式是兼容的
    console.log(req.method)
    console.log(req.url)
    console.log(req.httpVersion)
    console.log(req.headers)

    // 2  express 独有的获取报文的方式
    // 获取path
    console.log(req.path)
    // 获取查询字符串
    console.log(req.query)
    // 获取ip
    console.log(req.ip)
    // 获取指定的请求头
    console.log(req.get('host'))

    res.send('请求报文的获取')
})

app.listen(3000,()=>{
    console.log('服务启动成功,端口3000')
})
3.4获取路由参数

路由参数指的是URL路径中的参数

const express = require("express");

const app = express();

app.get("/:id.html", (req, res) => {
    console.log(req.params.id)
  res.setHeader("content-type", "text/html;charset=utf-8");
  res.send("商品详情");
});

app.listen(3000, () => {
  console.log("服务器启动成功");
});
四、响应设置

expres框架封装了一些API来方便给客户端响应数据,并且兼容原生HTTP模块获取方式

const express = require("express");

const app = express();

// 创建路由
app.get("/response", (req, res) => {
  //   // 原生响应
  //   res.statusCode = 404;
  //   res.statusMessage = "l"
  //   res.setHeader('xxx','yyy')
  //   res.write('hello express')
  //   res.end("response");

  // express响应
  res.status(500); //设置响应状态码
  res.set("aaa", "bbb"); //设置响应头
  res.send("你好 express"); //设置响应体

  // 连贯操作
  res.status(404), set("ccc", "sss").send("你好");

  // 其他响应
  res.redirect("http://atguigu.com"); //重定向
  res.download("./package.json"); //下载响应
  res.json(); //设置响应json
  res.sendFile("__dirname" + "/home.html"); //响应文件内容
});

app.listen(3000, () => {
  console.log("服务器启动,端口号3000");
});

五、express中间件
5.1、什么是中间件

中间件(MiddleWare)本质是一个回调函数

中间件可以像路由回调一样访问请求对象,响应对象(response)

5.2、中间件的作用

中间件的作用就是使用函数封装公共操作,简化代码

5.3、中间件的类型
  • 全局中间件
  • 路由中间件
5.3.1 定义全局中间件

每一个请求到达服务端之后,都会执行全局中间件函数

// 记录每个请求的url 与 IP地址
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()
}
// 使用中间件函数
app.use(recordMiddleware);

app.get("/home", (req, res) => {
  res.send("前台首页");
});
app.get("/admin", (req, res) => {
  res.send("后台首页");
});

app.all("*", (req, res) => {
  res.send("<h1>404 not Found</h1>");
});

app.listen(3000, () => {
  console.log("服务器启动");
});

5.3.1 定义路由中间件

受约束的路由,都会执行中间件函数

// 针对 /admin /setting 的请求,要求URL携带code=521参数,如未携带提示[暗号错误]
const express = require("express");
const app = express();

app.get("/home", (req, res) => {
  res.send("前台首页");
});

// 声明路由中间件 函数形式没有约束
let checkCodeMiddleware = (req, res, next) => {
  // 判断URL中是否code参数等于521
  if (req.query.code == "521") {
    next();
  } else {
    res.send("暗号错误");
  }
};

app.get("/admin", checkCodeMiddleware, (req, res) => {
  res.send("后台首页");
});
app.get("/setting", checkCodeMiddleware, (req, res) => {
  res.send("设置");
});
app.all("*", (req, res) => {
  res.send("404 not Found");
});
app.listen(3000, () => {
  console.log("服务器启动成功");
});
5.4、静态资源中间件

express内置处理静态资源的中间件

const express = require("express");
const app = express();

// 静态资源中间件
app.use(express.static(__dirname+'/public'))

app.get("/home", (req, res) => {
  res.send("前台首页");
});


app.listen(3000, () => {
  console.log("服务器启动成功");
});

注意事项:

  • index.html 文件为默认打开的资源
  • 如果静态资源与路由规则同时匹配,谁先匹配谁就响应
  • 路由响应动态资源,静态资源中间件响应静态资源
5.5、获取请求体数据 body-parser

express可以使用body-parser 包处理请求体

第一步 安装

npm i body-parser

第二步 导入body-parser包

const bodyParser = require('body-parser')

第三步 获取中间件函数

//处理querystring格式的请求体
let urlParser = bodyParser.urlencoded({extend:false})
//处理JSON格式的请求体
let jsonParser = bodyParser.json()

第四步 设置路由中间件 然后使用request.body 来获取请求体数据

app.post('/login',urlParser,(req,res)=>{
	//获取请求体数据
    console.log(requset.body)
    //用户名
    console.log(requset.body.name)
    //密码
    console.log(requset.body.userpass)
    response.send('获取请求体数据')
})

练习:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <form action="http://127.0.0.1:3000/login" method="post">
        用户名:<input type="text" name="username">
        密码:<input type="password" name="userpass">
        <button>登录</button>
    </form>
</body>
</html>
/* 
    按照要求搭建HTTP服务

    GET   /login 显示表单网页
    POST  /login 获取表单中的 用户名 和 密码

*/

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

//设置路由中间件 处理querystring格式的请求体
let urlParser = bodyParser.urlencoded({ extend: false });

app.get("/login", (req, res) => {
  // res.send('表单页面')
  res.sendFile(__dirname + "/11_from.html");
});

app.post("/login", urlParser, (req, res) => {
  // 获取请求体数据
  console.log(req.body);
  res.send("获取用户数据");
});

app.listen(3000, () => {
  console.log("服务器启动");
});

5.6、防盗链小实践:
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)
        let hostname = url.hostname
        if(hostname !=='127.0.0.1'){
            res.status(404)
            res.send('<h1>404 Not Found</h1>')
            return
        }
    }
    console.log(referer)
    next()
})

// 静态资源中间件
app.use(express.static(__dirname+'/public'))

app.listen(3000, () => {
  console.log("服务器启动成功");
});
六、路由模块化

server.js

const express = require("express");
const homeRouter = require("../Express/routes/homeRoute");
const adminRouter = require("../Express/routes/adminRoute");

const app = express();

app.use(homeRouter);
app.use(adminRouter);

app.all("*", (req, res) => {
  res.send("404 not Found");
});

app.listen(3000, () => {
  console.log("服务器启动成功");
});

homeRoute.js

const express = require('express')

// 创建路由对象
const router = express.Router()

// 接口
router.get('/search',(req,res)=>{
    res.send('内容搜索')
})
router.get("/home", (req, res) => {
  res.send("前台首页");
});

module.exports = router;

adminRoute.js

const express = "express";
const router = express.Router();

router.get("/admin", (req, res) => {
  res.send("后台首页");
});
router.get("/setting", (req, res) => {
  res.send("设置");
});

module.exports=router;

七、模板引擎
7.1、什么是模板引擎

模板引擎是分离用户界面和业务数据的一种技术

7.2、什么是EJS

ESJ是一个高效的Javascript的模板引擎

官网:https://ejs.co/

中文站:https://ejs.bootcss.com/

7.3、EJS初体验

下载安装ESJ

npm i ejs --save

示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>你好,<%= china%></h1>
</body>
</html>
const ejs = require('ejs')
const fs= require('fs')

// 字符串
let china = '中国'
let str = `你好 ${china}`

// 使用ejs渲染
let str1 ='你好<%= china%>'
let result = ejs.render(str1,{china:china})

let str2 = fs.readFileSync('./01.html').toString()
let result2 = ejs.render(str2,{china:china})

console.log(result)
console.log(result2)
7.4、列表渲染

js:

const ejs = require("ejs");
const honglou = ["妙玉", "黛玉", "宝玉", "红玉"];
// // 原生JS
// let str = '<ul>'
// honglou.forEach(item=>{
//     str += `<li>${item}</li>`
// })
// //闭合ul
// str+='<ul>'

//ejs 实现
const fs = require("fs");
let html = fs.readFileSync("./02_红楼.html").toString();
let result = ejs.render(html, { honglou: honglou });

console.log(result);

html

<ul>
  <% honglou.forEach((item)=>{%>
  <li><%= item %></li>
  <% })%>
</ul>

7.5、条件渲染

js

/* 
通过 isLogin 决定最终输出的内容
true 输出 <span>欢迎回来</span>
false 输出 <button>登录</button> <button>注册</button>
*/
// 变量
let isLogin = true;
//原生JS
if (isLogin) {
  console.log(`<span>欢迎回来</span>`);
} else {
  console.log(`<button>登录</button> <button>注册</button>`);
}

// ejs实现
const ejs = require("ejs");
const fs = require("fs");
let html = fs.readFileSync('./03_条件渲染.html').toString();
let result = ejs.render(html, { isLogin: isLogin });
console.log(result);

html

<% if(isLogin){%>
<span>欢迎回来</span>
<% }else{ %>
<button>登录</button> <button>注册</button> <% } %>

7.5、在express框架中使用

home.ejs

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h2><%= title %></h2>
</body>
</html>

js

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

const app = express();

// 设置模板引擎
app.set("view engine", 'ejs');
// 设置模板存放的位置
app.set("views", path.resolve(__dirname, "./views"));

app.get("/home", (req, res) => {
  let title = "哈哈哈哈";
  res.render("home", { title });
});

app.listen(3000, () => {
  console.log("服务器启动");
});

八、express-generator工具

通过应用生成工具express-generator可以快速创建一个应用的骨架

安装:

npm install -g express-generator

创建

express -e 15_generator
-e//添加ejs引擎
15_generator//文件夹名称

安装依赖

npm i
九、文件上传

处理文件请求

安装:formidable

npm i formidable 

portrait.ejs

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>文件上传</title>
  </head>
  <body>
    <h2>文件上传</h2>
    <hr />
    <!-- 文件上传的必须属性 -->
    <from action="/portrait" method="post" enctype="multipart/form-data">
        用户名:<input type='text' name="username"><br>
        头像:<input type="file" name="portrait"><br>
        <hr>
        <button>点击提交</button>
    </from>
  </body>
</html>

index.js

var express = require("express");
var router = express.Router();

/* GET home page. */
router.get("/", function (req, res, next) {
  res.render("index", { title: "Express" });
});

// 显示网页的表单
router.get("/portrait", (req, res) => {
  res.render("portrait");
});
// 处理文件上传
router.post("/portrait", (req, res) => {
  // 创建from对象
  const form = formidable({
    multiples: true,
    //设置文件上传保存目录
    uploadDir: __dirname + "../public/images",
    //保持文件后缀
    keepExtensions: true,
  });
  // 解析请求报文
  form.parse(req, (err, fields, files) => {
    if (err) {
      next(err);
      return;
    }
    console.log(fields);
    console.log(files);
    res.json({ fields, files });
    // 服务器保存该图片的访问url
    let url = "/images/" + files.portrait.newFilename; //此数据保存数据库
    res.send(url);
  });
});

module.exports = router;


Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐