express框架学习笔记

express简介

express是一个基于Node.js平台的极简的、灵活的WEB应用开发框架。express是一个封装好的工具包,封装了很多功能,便于我们开发WEB应用(HTTP服务)

express使用

新建express文件夹新建文件test01.js,代码如下

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

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

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

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

npm初始化,然后新建express-learn,接着运行node test01.js,报错
在这里插入图片描述

在目录下安装express并将其保存到依赖列表

npm install express --save

运行成功。
只有请求方法是get请求路径是/home的时候回调函数才会实现,请求的url路径是/,所以响应404
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

express路由

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

express路由的使用

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

app.<method>(path.callback)

GET请求

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

POST请求

app.post('/login', (req, res) => {
    res.end('i m login')
})

使用表单发送post请求

   <form method="post" action="http://127.0.0.1:3000">
        <button>登录</button>
    </form>

其他的一些具体案例

//post
app.post('/login', (req, res) => {
    res.end('i m login')
});
// 匹配所有的方法
app.all('/test', (req, res) => {
    res.end('test')
})
// 404响应
app.all('*', (req, res) => {
    res.end('404 not found')
})

在这里插入图片描述
在这里插入图片描述

注意路径名不要添加点,不然可能会出现错误

获取报文数据

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

核心代码

 // 获取查询字符串
    console.log(req.query);
    // 获取指定的请求头
    console.log(req.get('host'));

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

在这里插入图片描述

获取路由参数

商城中的商品的id不同,对应的商品详情页面也不相同,所以使用下面的代码匹配

app.get('/:id.html', (req, res) => {
    // 获取URL路由参数
    console.log(req.params.id);
    res.getHeader('content-type', 'text/html;charset=utf-8');
    res.end('商品详情');
});

两个id名称保持一致。
在这里插入图片描述
在这里插入图片描述

express响应设置

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

app.get("/response", (req, res) => {
    // express中设置响应的方式兼容HTTP模块的方式
    res.statusCode = 404;
    res.statusMessage = 'xxx';
    res.setHeader('abc', 'xyz');
    res.write('响应体');
    res.end('xxx');
    })

express的响应方法

    res.status(500);
    res.set('xxx', 'yyy');
    res.send('中文响应不乱码');
    // 连贯操作
    res.status(404).set('xxx', 'yyy').send('你好朋友')
    // 3其他响应
    res.redirect('http://xxx.com')//重定向
    res.download('./package.json');//下载响应
    res.json();//响应json
    res.sendFile(__dirname + '/home.html')//响应文件内容

json响应可以是下面这样

  res.json({
        name: '隐藏用户',
        rank: 'top1'
    });

将html文件内容响应给网页可以使用

res.sendFile(_dirname+'/test.html')

或者是path.resolve()

中间件

Middleware本质是一个回调函数,中间件函数可以像路由回调一样访问请求对象(request),响应对象response

中间件的作用

使用函数封装公共操作,简化代码

中间件的类型

  • 全局中间件
  • 路由中间件

定义全局中间件

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

执行下面的函数

app.get('/home', (req, res) => {
    // 获取url和ip
    let { url, ip } = req;
    // 将信息保存在文件中access.log
    fs.appendFileSync(path.resolve(__dirname, './access.log'), `${url}  ${ip}\r\n`);///home 127.0.0.1
    res.send('前台首页');
});

推荐插件Template String Converter,可以在${}输入字符串时候自动生成反引号
在这里插入图片描述
在这里插入图片描述

每个路由规则都要写app.get里面的两行代码,先上车后检查的类似操作后续维护不便,这是我们可以考虑中间件操作

function recordMiddleware(req, res, next) {
    // 获取url和ip
    let { url, ip } = req;
    // 将信息保存在文件中access.log
    fs.appendFileSync(path.resolve(__dirname, './access.log'), `${url}  ${ip}\r\n`);///home 127.0.0.1
    // 调用next
    next();
}
// 使用中间件函数
app.use(recordMiddleware);

req是接收请求报文的对象,res是接收响应报文的对象,next是内部函数,执行后指向路由回调或者中间件回调.

路由中间件实践

需求:针对/admin /setting的请求,要求URL携带code=521的参数,如未携带提示【暗号错误】;
声明中间件函数,并设置在受约束的路由规则当中

// 声明中间件
let checkCodeMiddleware = (req, res, next) => {
    // 判断URL中的是否code参数等于521
    if (req.query.code === '521') {
        // res.send('登录页面');不能每个请求都响应登录页面,这样其他页面都失效了
        next();//满足条件就可以执行后续代码
    } else {
        res.send('暗号错误');
    }
}
app.get('/admin', checkCodeMiddleware, (req, res) => {
    res.send('后台首页');
});
// 后台设置
app.get('/setting', checkCodeMiddleware, (req, res) => {
    res.send('设置页面');
});

在这里插入图片描述

先执行中间件里面的代码,执行next,执行路由回调。路由中间件就可以封装代码。项目中一般使用中间件校验用户身份或者权限。

静态资源中间件

静态资源中间件的设置

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

express.static()返回结果是一个中间件函数,参数是静态资源文件夹的路径,服务端到文件夹寻找对应文件,读取文件,响应内容。
在这里插入图片描述

注意事项

  1. express.html文件为默认打开的资源
    在这里插入图片描述

  2. 如果静态资源和路由规则同时匹配,谁先匹配谁就响应

   app.use(express.static(__dirname + '/public'));


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

两个同时匹配上,先匹配前面的就先响应前面的
3. 路由响应动态资源,静态资源中间件响应静态资源

获取请求体数据

核心步骤

  1. 安装
  2. 导入包
  3. 获取中间件函数
  4. 设置路由中间件,然后使用request.body来获取请求体数据

需求

按照要求搭建HTTP服务
get /login 显示表单网页
post /login 获取表单中的用户名和密码

const express = require('express');
const bodyParser = require('body-parser');

const app = express();

app.get('/login', (req, res) => {
    res.send('表单页面')
});

app.post('/login', (req, res) => {
    res.send('获取用户的数据')
});
app.listen(3000, () => {
    console.log('服务已启动')
})

在这里插入图片描述

post请求需要用表单来发起,新建form表单,修改路由规则里面响应html内容

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

在这里插入图片描述

因为响应的表单数据是querystring格式的,所以使用第二个

//解析json格式的请求体的中间件
var jsonParser = bodyParser.json()

// 解析querystrinng格式请求体的中间件
var urlencodedParser = bodyParser.urlencoded({ extended: false })

app.post('/login', urlencodedParser, (req, res) => {
    console.log(req.body);
    res.send('获取用户的数据');
});

防盗链

在网页中选择图片,右键复制图片链接,将其引入html的img里面,打开html,有的显示有的不显示,不显示的就是开启了防盗链。防止外部网站盗用本网站资源。

设置一张图片可以127.0.0.1访问禁止localhost访问

// 声明中间件
app.use((req, res, next) => {
    // 检测请求头中的referer是否为127.0.0.1
    // 获取referer
    let referer = req.get('referer');
    if (referer) {//有refer进入函数内,没有直接下一步
        // 实例化
        let url = new URL(referer);
        // 获取hostname
        let hostname = url.hostname;
        console.log(hostname)
        if (hostname !== '127.0.0.1') {
            res.status(404).send('<h1>404</h1>')
        }
    }
    console.log(referer);
    next();
})
app.use(express.static(__dirname + '/public'));

在这里插入图片描述
在这里插入图片描述

路由模块化

将路由的代码进行模块化处理,将13文件中的前台的路由移动到homeRouter.js中,然后在13文件中导入homeRouter,设置app.use(homeRouter)

主要步骤

  1. 导入express
  2. 创建路由对象
  3. 创建路由规则
  4. 暴露router
    在文件13中引入
const homeRouter = require('./homeRouter')
app.use(homeRouter);

homeRouter的代码

const express = require('express');
const router = express.Router();
router.get('/home', (req, res) => {
    res.send('前台首页');
});
router.get('/search', (req, res) => {
    res.send('内容搜索');
});
module.exports = router;

在这里插入图片描述
在这里插入图片描述

后台也可以路由模块化处理。

EJS模板引擎

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

EJS是一个高效的JavaScript的模板引擎。

使用方法

下载安装

npm i ejs --save

使用步骤

  1. 下载安装
  2. 引入ejs
  3. 定义数据
  4. ejs解析模板返回结构

ejs列表渲染

const ejs = require('ejs');
let person = ['张三', '李四', '二狗'];
// js
let str = '<ul>';
person.forEach(item => {
    str += `<li>${item}</li>`;
})

str += '</ul>';
console.log(str);
// ejs
let result = ejs.render(`<ul>
<% person.forEach(item =>{ %>
    <li><%= item %></li>
    <% }) %>
    </ul>`, { person: person });

console.log(result)

在这里插入图片描述
在这里插入图片描述

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

写入html文件,然后编写EJS

const fs = require('fs');
let html = fs.readFileSync('./02ejs.html').toString();
let result = ejs.render(html, { person: person });

console.log(result)

在这里插入图片描述

EJS条件渲染

需求:通过isLogin决定最终的输出内容
true 输出 欢迎回来
false输出登录 注册

// 变量
let isLogin = true;

// 原生js
if (isLogin) {
    console.log('<span>欢迎回来</span>')
} else {
    console.log('<button>登录</button> <button>注册</button>')
}

// ejs
let result = ejs.render(`
    <% if(isLogin){%>
<span>欢迎回来</span>
   <% }else{%>
   <button>登录</button> <button>注册</button>
    <% }%>`,
    { isLogin: isLogin }
);

左边的isLogin和if里面的保持一致,,右边的和变量名称保持一致.
进一步操作,将ejs代码剪切到html中

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

在js文件中读取html文件

let html=fs.readFileSync('./_home.html').toString();

运行报错,原因忘记引入fs模块和ejs模块,引入后运行截图
在这里插入图片描述

express中使用ejs

模板文件:具有模板语法的文件,比如之前具有模板语法的html文件

res.render(‘模板的文件名’,‘数据’)

// 导入express
const express = require('express');
// 创建应用对象
const app = express();
//1. 设置模板引擎
app.set('view engine', 'ejs')
// 2.设置模板文件存放位置
app.set('views', path.resolve(__dirname, './views'));


// 创建路由
app.get('/home', (req, res) => {
    //    3.render响应
    //声明变量
    let title = '隐藏用户top1';
    res.render('home', { title });
    // 4.模板文件

});

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

express-generator

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

安装使用

npm install -g express-generator

安装完成后使用express -h可以查看帮助
在这里插入图片描述

将代码下载到一个新的文件夹下面

express -e  文件夹名称

新建的文件夹为generator,在generator里面安装依赖npm i
之后可以使用npm start运行项目
404的两种写法

 app.use(function(req, res, next) {
  next(createError(404));
});
app.all('*', (req, res) => {
    res.end('404 not found')
})

查看文件上传报文

multipart/form-data是文件上传的必需属性。

在这里插入图片描述

npm start运行之后报错,
在这里插入图片描述

原因在于index.js里面没有写post
在这里插入图片描述

机械的敲代码,看走眼了。。。

修改之后页面功能全部正常

处理文件上传

首先安装一个包formidable

npm i formidable

引入formidable然后写入下面的代码

router.post('/portrait', (req, res) => {
  // 创建form对象
  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);
    // 服务器保存该图片的访问url
    let url = '/images/' + files.portrait.newFilename;//将来将此数据保存在数据库中
    res.send('ok')
    // res.json({ fields, files });
  });
', (req, res) => {
  // 创建form对象
  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);
    // 服务器保存该图片的访问url
    let url = '/images/' + files.portrait.newFilename;//将来将此数据保存在数据库中
    res.send('ok')
    // res.json({ fields, files });
  });

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/30513.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

深蓝学院C++基础与深度解析笔记 第 5 章 语句

1. 语句基础 ● 语句的常见类别 – 表达式语句&#xff1a;表达式后加分号&#xff0c;对表达式求值后丢弃&#xff0c;可能产生副作用 – 空语句&#xff1a;仅包含一个分号的语句&#xff0c;可能与循环一起工作 – 复合语句&#xff08;语句体&#xff09;&#xff1a;由大…

电商数仓(用户行为采集平台)数据仓库概念、用户行为日志、业务数据、模拟数据、用户行为数据采集模块、日志采集Flume

1、数据仓库概念 数据仓库&#xff08; Data Warehouse &#xff09;&#xff0c;是为企业制定决策&#xff0c;提供数据支持的。可以帮助企业&#xff0c;改进业务流程、提高产品质量等。 数据仓库的输入数据通常包括&#xff1a;业务数据、用户行为数据和爬虫数据等。 业务数…

流场粒子追踪精度数值实验

在计算流线&#xff0c;拉格朗日拟序结构等流场后处理时&#xff0c;我们常常需要计算无质量的粒子在流场中迁移时的轨迹&#xff0c;无质量意味着粒子的速度为流场当地的速度。此时&#xff0c;求解粒子的位移这个问题是一个非常简单的常微分方程问题。 假设流场中存在 i 个粒…

Java版本+企业电子招投标系统源代码之电子招投标系统建设的重点和未来趋势

计算机与网络技术的不断发展&#xff0c;推动了社会各行业信息化的步伐。时至今日&#xff0c;电子政务、电子商务已经非常普及&#xff0c;云计算、大数据、工业4.0、“互联网”等发展理念也逐步深入人心&#xff0c;如何将传统行业与互联网科技有效结合起来&#xff0c;产生1…

Vue实现元素沿着坐标数组移动,超出窗口视图时页面跟随元素滚动

一、实现元素沿着坐标数组移动 现在想要实现船沿着下图中的每个河岸移动。 实现思路&#xff1a; 1、将所有河岸的位置以 [{x: 1, y: 2}, {x: 4, y: 4}, …] 的形式保存在数组中。 data() {return {coordinateArr: [{ x: 54, y: 16 }, { x: 15, y: 31 }, { x: 51, y: 69 }…

升级Nginx

目录 前言 一、升级Nginx 1&#xff09;首先在官网下载一个新版本的Nginx 2&#xff09;首先将下载的压缩包进行解包 3&#xff09;进入已解包的目录中 4&#xff09;配置安装路径 5&#xff09;make 6&#xff09;备份原来Nginx的资源 7&#xff09;重启Nginx服务 8&#…

【2023最全教程】Web自动化测试怎么做?Web自动化测试的详细流程和步骤

一、什么是web自动化测试 自动化&#xff08;Automation&#xff09;是指机器设备、系统或过程&#xff08;生产、管理过程&#xff09;在没有人或较少人的直接参与下&#xff0c;按照人的要求&#xff0c;经过自动检测、信息处理、分析判断、操纵控制&#xff0c;实现预期的目…

毕业季Android开发面试,有哪些常见的题?

前言 对于计算机行业早已烂大街&#xff0c;随之而来的毕业季。还会有大批的程序员涌进来&#xff0c;而我们想要继续进入Android开发岗位的人员&#xff0c;最先考虑的是面试。面试题是我们决定踏进工作的重要环节。 对于刚毕业的实习生来说&#xff0c;如何在应聘中脱颖而出…

LightningChart .NET 10.5.1 Crack LightningChart 2023

LightningChart .NET v.10.5.1 已经发布&#xff01; DataCursor 和 3D TransparencyRenderMode 现在可用。 为所有 3D、Polar 和 Smith 系列启用 DataCursor 在早期阶段&#xff0c;LightningChart 提供了不同的工具&#xff0c;需要用户编写额外的代码才能启用数据跟踪功能。…

控制您的数据:Web3私有链为数据主权带来的突破性变革

在数字化时代&#xff0c;数据已经成为企业和个人最宝贵的资产之一。然而&#xff0c;随着大规模数据泄露和滥用事件的频发&#xff0c;数据主权和隐私保护成为了备受关注的问题。在这个背景下&#xff0c;Web3私有链的出现为数据主权带来了一场突破性的变革。 首先&#xff0c…

风景类Midjourney prompt提示词

稳定输出优美风景壁纸的Midjourney prompt提示词。 1\在夏夜&#xff0c;有淡蓝色的星空&#xff0c;海边&#xff0c;流星&#xff0c;烟花&#xff0c;海滩上全是蓝色的玫瑰和绿色的植物&#xff0c;由Ivan Aivazovsky和Dan Mumford&#xff0c;趋势在cgsociety&#xff0c;…

windows2022证书配置.docx

Windows证书的配置 要求两台主机&#xff0c;一台作为域&#xff0c;一台进入域 按要求来选择角色服务 确认之后安装 安装完以后配置证书服务 选择服务 按要求配置 注&#xff1a;此处不用域用户登陆无法使用企业CA 按要求来 创建新的私钥 这几处检查无误后默认即可 有效期…

AJAX概述

1.1什么是AJAX. Ajax即AsynchronousJavascript And XML&#xff1a;异步数据回调。 使用Ajax技术网页应用能够快速地将更新呈现在用户界面上&#xff0c;不需要重载&#xff08;刷新&#xff09;整个页面【只刷新局部】&#xff0c;这使得程序能够更快地回应用户的操作。、 1…

2023年5月青少年机器人技术等级考试理论综合试卷(四级)

青少年机器人技术等级考试理论综合试卷&#xff08;四级&#xff09;2023.6 分数&#xff1a; 100 题数&#xff1a; 30 一、 单选题(共 20 题&#xff0c; 共 80 分) 1.Arduino C 语言&#xff0c; 部分程序如下&#xff0c; 串口监视器输出结果是“D”时&#xff0c; 变量 i …

【集群】Haproxy搭建Web群集

文章目录 一、Haproxy 相关概念1. Haproxy 的概述2. Haproxy 的主要特性3. 常见的 Web 集群调度器4. 常见的应用分析4.1 LVS 应用4.2 Haproxy 应用4.3 LVS、Nginx、Haproxy的区别 5. Haproxy 调度算法原理5.1 roundrobin5.2 static-rr5.3 leastconn5.4 source5.5 uri5.6 url_pa…

SpringBoot + Vue前后端分离项目实战 || 二:Spring Boot后端与数据库连接

系列文章&#xff1a; SpringBoot Vue前后端分离项目实战 || 一&#xff1a;Vue前端设计 文章目录 新建Spring后台项目添加依赖 新建数据库IDEA 连接数据库IDEA 自动创建类实体定义数据传递至前端的格式 B站视频讲解&#xff1a;2023全网最简单但实用的SpringBootVue前后端分离…

RTC

文章目录 前言驱动应用程序运行 前言 RTC&#xff08;Real Time Clock&#xff0c;实时时钟&#xff09;是个常用的外设&#xff0c;通过 RTC 我们可以知道日期和时间信息&#xff0c;因此在需要记录时间的场合就需要实时时钟。 可以使用专用的实时时钟芯片来完成此功能&#…

扫雷小游戏【C语言】

目录 前言 一、基本实现逻辑 二、实现步骤 1. 我们希望在进入游戏时有一个菜单让我们选择 2. 我们希望可以重复的玩&#xff08;一把玩完了还可以接着玩&#xff09; 3. 采用多文件形式编程 4.要扫雷先得有棋盘&#xff08;创建棋盘R*N&#xff09; 5.初始化棋盘 6.打…

【网络安全】深入解析 PHP 代码审计技术与实战

前言 登录某个网站并浏览其页面时&#xff0c;注意到了一些看起来不太对劲的地方。这些迹象可能是该网站存在漏洞或被黑客入侵的标志。为了确保这个网站的安全性&#xff0c;需要进行代码审计&#xff0c;这是一项专门针对软件代码进行检查和分析的技术。在本文中&#xff0c;…

一、Docker介绍

学习参考&#xff1a;尚硅谷Docker实战教程、Docker官网、其他优秀博客(参考过的在文章最后列出) 目录 前言一、Docker是什么&#xff1f;二、Docker能干撒&#xff1f;三、容器虚拟化技术 和 虚拟机有啥区别&#xff1f;1.虚拟机2.容器虚拟化技术3.对比4.Docker为啥比VM虚拟机…