Express安装与基础使用

一、express 介绍

express 是一个基于 Node.js 平台的极简、灵活的 WEB 应用开发框架,
官方网站: Express - 基于 Node.js 平台的 web 应用开发框架 - Express中文文档 | Express中文网
中文文档: 路由 - Express 中文文档
简单来说, express 是一个封装好的工具包,封装了很多功能,便于我们开发 WEB 应用( HTTP 服务)

二、express 使用

2.1 express 下载

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

2.2 express 基本使用

1、基础代码
//1. 导入 express
const express = require('express');

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

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

//4. 监听端口 启动服务
app.listen(3000, () =>{
  console.log('服务已经启动, 端口监听为 3000...');
});
2. 命令行下执行该脚本
node < 文件名 >
# 或者
nodemon < 文件名 >
3. 然后在浏览器就可以访问 http://127.0.0.1:3000/home

2.3 获取请求参数

express 框架封装了一些 API 来方便获取请求报文中的数据,并且兼容原生 HTTP 模块的获取方法
//导入 express
const express = require('express');
//创建应用对象
const app = express();
//获取请求的路由规则
app.get('/hh', (req, res) => {
//1. 获取报文的方式与原生 HTTP 获取方式是兼容的
  console.log("请求方法", req.method); //获取请求方法
  console.log("请求路径", req.url); //获取请求路径
  console.log("协议版本", req.httpVersion); // 获取协议版本
  console.log("请求头", req.headers); // 获取请求头

  //express 操作
  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('启动成功....')
})
控制台打印如下:

2.4 获取路由参数

路由参数指的是 URL 路径中的参数(数据)
router.get("/users/:userId/books/:bookId", function (req, res, next) {
  //获取 URL 路由参数
  console.log("URL 路由参数", req.params);
  res.setHeader("content-type", "text/html;charset=utf-8");
  res.send({ h: "hello" });
});

控制台打印如下:

三、express 响应设置

express 框架封装了一些 API 来方便给客户端响应数据,并且兼容原生 HTTP 模块的获取方式
router.get("/response", function (req, res, next) {
  //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("https://www.baidu.com/"); //重定向
  // res.download("./package.json"); //下载响应
  // res.json(); //响应 JSON
  res.send({ h: "hello" });
});

四、express 中间件

4.1 什么是中间件

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

4.2 中间件的作用

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

4.3 中间件的类型

全局中间件
路由中间件
4.3.1 定义全局中间件
每一个请求 到达服务端之后 都会执行全局中间件函数
声明中间件函数
/**
 * 记录每个请求的 url 与 IP 地址
 */
//导入 express
const express = require("express");
const fs = require("fs");
const path = require("path");

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

//声明中间件函数 名字自定义
function recordMiddleware(req, res, next) {
  // res 接受请求报文的对象
  // 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.all("*", (req, res) => {
  res.send("<h1>404 Not Found</h1>");
});

//监听端口, 启动服务
app.listen(3000, () => {
  console.log("服务已经启动, 端口 3000 正在监听中....");
});
应用中间件
app.use(recordMiddleware);

4.3.2 定义路由中间件
如果 只需要对某一些路由进行功能封装 ,则就需要路由中间件
调用格式如下:
app.get('/路径',`中间件函数`,(request,response)=>{
});
app.get('/路径',`中间件函数1`,`中间件函数2`,(request,response)=>{
});

使用:

//声明中间件
let checkCodeMiddleware = (req, res, next) => {
  //判断 URL 中是否 code 参数等于 521
  if (req.query.code === "521") {
    next();
  } else {
    res.send("暗号错误");
  }
};
router.get("/kkl", checkCodeMiddleware, function (req, res, next) {
  res.send({ h: "hello" });
});

4.4 静态资源中间件

//引入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 端口启动....');
});
注意事项:
1. index.html 文件为默认打开的资源
2. 如果静态资源与路由规则同时匹配,谁先匹配谁就响应
3. 路由响应动态资源,静态资源中间件响应静态资源

4.5 获取请求体数据 body-parser

官网:body-parser - npm

express 可以使用 body - parser 包处理请求体
npm i body-parser --save
第二步:导入 body-parser
const bodyParser = require('body-parser');
第三步:获取中间件函数
//处理 querystring 格式的请求体
let urlParser = bodyParser.urlencoded({extended:false}));
//处理 JSON 格式的请求体
let jsonParser = bodyParser.json();
第四步:设置路由中间件,然后使用 request.body 来获取请求体数据
app.post('/login', urlParser, (request,response)=>{
//获取请求体数据
//console.log(request.body);
//用户名
console.log(request.body.username);
//密码
console.log(request.body.userpass);
response.send('获取请求体数据');
});
获取到的请求体数据:
const bodyParser = require("body-parser");
//解析 JSON 格式的请求体的中间件
// const jsonParser = bodyParser.json()

//解析 querystring 格式请求体的中间件
const urlencodedParser = bodyParser.urlencoded({ extended: false });
router.get("/dd", urlencodedParser, function (req, res, next) {
  // 当中间件urlencodedParser 执行完之后,它会向res 添加一个参数名字为 body,里面有请体的参数
  console.log(req.body);
  res.send({ h: "hello" });
});

五、Router

5.1 什么是 Router

express 中的 Router 是一个完整的中间件和路由系统,可以看做是一个小型的 app 对象。

5.2 Router 作用

对路由进行模块化,更好的管理路由

5.3 Router 使用

创建独立的 JS 文件( homeRouter.js
//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 端口启动....');
})

六、防盗链

6.1 什么是防盗链:

就是禁止别人引用自己网站的资源,保护自己网站的资源,或者减少服务器压力,比如图片的引用

6.2 使用

// 防盗链的使用  使用中间件
const stopHttp = (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;
    //判断
    if (hostname !== "127.0.0.1") {
      //响应 404
      res.status(404).send("<h1>404 Not Found</h1>");
      return;
    }
  }
  next();
};
router.get("/cc", stopHttp, function (req, res, next) {
  //  只许可 网站 127.0.0.1 访问该资源
  res.send({ h: "hello" });
});

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

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

相关文章

二次开发在线预约上门服务、预约到家系统 增加开发票功能 轮播图链接跳转 uniapp代码

客户具体要求&#xff1a; 1、在我的个人中心里面增加一个 开票功能&#xff0c;点击进去之后可以查看到能开票的订单列表&#xff0c;如果是个人是填写姓名电话邮箱&#xff0c;就是填写单位名称 税号 邮箱&#xff0c;提交申请到后台审核&#xff0c;如果审核通过后线下人工…

预处理/预编译详解(C/C++)

在上一篇的bolg中的编译与链接中提到过预处理&#xff0c;但只是较为简单的讲解&#xff0c;本篇将会对预处理进行详细的讲解。 其中在预处理中很重要的一个一个知识点是#define定义常量与宏&#xff0c;还区分了宏与函数的区别&#xff0c;以及#和##符号&#xff0c;还涉及条件…

ADA-YOLO:YOLOv8+注意力+Adaptive Head,mAP提升3%

生物医学图像分析中的目标检测和定位至关重要&#xff0c;尤其是在血液学领域&#xff0c;检测和识别血细胞对于诊断和治疗决策至关重要。虽然基于注意力的方法在各个领域中目标检测方面取得了显著的进展&#xff0c;但由于医学影像数据集的独特挑战&#xff0c;其在医学目标检…

【用队列实现栈】【用栈实现队列】Leetcode 232 225

【用队列实现栈】【用栈实现队列】Leetcode 232 225 队列的相关操作栈的相关操作用队列实现栈用栈实现队列 ---------------&#x1f388;&#x1f388;题目链接 用队列实现栈&#x1f388;&#x1f388;------------------- ---------------&#x1f388;&#x1f388;题目链…

vue2使用qiankun微前端(跟着步骤走可实现)

需求&#xff1a;做一个vue2的微前端&#xff0c;以vue2为主应用&#xff0c;其他技术栈为子应用&#xff0c;比如vue3&#xff0c;本文章只是做vue2一套的微前端应用实现&#xff0c;之后解决的一些问题。vue3子应用可以看我另一篇vue3vitets实现qiankun微前端子应用-CSDN博客…

IDEA 2022.3.3 安装教程

1.下载2022.3.3版本IDEA 链接&#xff1a;https://pan.baidu.com/s/1z-Yfl7fWHgqz8SQLn2-u0g?pwd949u 提取码&#xff1a;949u 2.安装 下载完成后&#xff0c;双击exe安装包&#xff0c; 点击next 3.选择方式3 4.将下面文件复制到任意位置&#xff08;不要有中文路径&…

❤ Uniapp使用二 ( 日常使用篇)

❤ Uniapp使用二 ( 日常使用篇) 一、表单 1、基础表单验证 form <form submit"formSubmit" reset"formReset"> <view class"uni-form-item uni-column"><view class"title">请选择类型{{selectvalue}}</view&…

VC++中使用OpenCV对原图像中的四边形区域做透视变换

VC中使用OpenCV对原图像中的四边形区域做透视变换 最近闲着跟着油管博主murtazahassan&#xff0c;学习了一下LEARN OPENCV C in 4 HOURS | Including 3x Projects | Computer Vision&#xff0c;对应的Github源代码地址为&#xff1a;Learn-OpenCV-cpp-in-4-Hours 视频里面讲…

【ubuntu】ubuntu 20.04安装docker,使用nginx部署前端项目,nginx.conf文件配置

docker 官网&#xff1a;Install Docker Engine on Ubuntu 一、安装docker 1.将apt升级到最新 sudo apt update2.使用apt安装 docker 和 docker-compose &#xff08;遇到提示输入y&#xff09; sudo apt install docker.io docker-compose3.将当前用户添加到docker用户组 …

网页设计(二)格式化文本、段落与列表

一、孔融让梨 【思政素材】 孔融&#xff0c;字文举&#xff0c;东汉时期中国山东曲阜人&#xff0c;是孔子的第二十世孙&#xff0c;是中国古代东汉末文学家。 孔融四岁的时候&#xff0c;和哥哥吃梨&#xff0c;总是拿小的吃。有人问他为什么这么做。他回答说&#xff1a;“…

Qt6入门教程 7:信号和槽机制(原理和优缺点)

目录 一.简介 二.信号和槽 1.信号和槽机制是类型安全的 2.信号和槽是松散耦合的 三.信号&#xff08;signals&#xff09; 四.槽&#xff08;slots&#xff09; 五.信号与槽的简单模拟 六.第三方信号槽实现 七.在Qt中使用第三方的Signals和Slots 八.总结一下优点和缺…

搜维尔科技:SenseGlove Nova 2力反馈技术手套,虚拟培训的沉浸感达到新高度!

SenseGlove Nova 2-虚拟培训的沉浸感达到新高度&#xff01; 通过集成主动接触反馈&#xff0c;Nova 2 使用户能够在手掌中感知虚拟现实物体的感觉。虚拟训练、研究和多人互动现在感觉比以往更加自然。这项创新增强了与整个手掌接触的任何虚拟物体的真实感。使用第一款也是唯一…

select子句简单查询

Oracle从入门到总裁:https://blog.csdn.net/weixin_67859959/article/details/135209645 目录 数据查询 起别名 连接 ​编辑 去重 ​编辑 另外补充几个不常用的命令 如果要进行查询,那么需要使用数据操纵语言&#xff08;Data Manipulation Language&#xff0c;DML&am…

mysql 下载和安装和修改MYSQL8.0 数据库存储文件的路径

一、第一步:下载步骤 下载链接&#xff1a;MySQL :: Download MySQL Installer 选择版本8.0.35&#xff0c;社区版&#xff0c; 点击 Download 下载 安装包 二、第二步:安装步骤 添加环境变量&#xff0c;C:\Program Files\MySQL\MySQL Server 8.0\bin 可以点开MySQL 8.0 Co…

三、基础篇 vue Class与Style绑定

操作元素的 class 列表和内联样式是数据绑定的一个常见需求。因为它们都是 attribute&#xff0c;所以我们可以用 v-bind 处理它们&#xff1a;只需要通过表达式计算出字符串结果即可。不过&#xff0c;字符串拼接麻烦且易错。因此&#xff0c;在将 v-bind 用于 class 和 style…

小程序基础学习(页面跳转传参)

目录 正向传参 原理&#xff1a;直接在url里面拼接参数即可 接受参数 ​编辑 已经跳转到的页面用onLoad函数来接受即可然后写回页面展示即可 逆向传参 原理&#xff1a;通过使用 getCurrentPages()这个方法来获取返回页面列表&#xff0c;然后再用页面.setData&#xff…

弟12章 网络编程

文章目录 网络协议概述 p164TCP协议与UDP协议的区别 p165TCP服务器端代码的编写 p166TCP服务器端流程 TCP客户端代码的编写 p167TCP客户端流程主机和客户端的通信流程 tcp多次通信服务器端代码 p168TCP多次通信客户端代码 p169UDP的一次双向通信 p170udp通信模型udp接收方代码u…

【C语言】ipoib驱动 - ipoib_cm_handle_rx_wc_rss

一、ipoib_cm_handle_rx_wc_rss函数定义 void ipoib_cm_handle_rx_wc_rss(struct net_device *dev, struct ib_wc *wc) {struct ipoib_dev_priv *priv ipoib_priv(dev);struct ipoib_cm_rx_buf *rx_ring;unsigned int wr_id wc->wr_id & ~(IPOIB_OP_CM | IPOIB_OP_RE…

Spring Boot框架中Controller层API接口如何支持使用多个@RequestBody注解接受请求体参数

一、前言 众所周知&#xff0c;在Spring Boot框架中&#xff0c;Controller层API接口编码获取请求体参数时&#xff0c;在参数上会使用RequestBody注解&#xff1b;如果一次请求中&#xff0c;请求体参数携带的内容需要用多个参数接收时&#xff0c;能不能多次使用RequestBody…

通过OpenIddict设计一个授权服务器02-创建asp.net项目

在这一部分中&#xff0c;我们将创建一个ASPNET核心项目&#xff0c;作为我们授权服务器的最低设置。我们将使用MVC来提供页面&#xff0c;并将身份验证添加到项目中&#xff0c;包括一个基本的登录表单。 创建一个空的asp.net core项目 正如前一篇文章中所说&#xff0c;授权…