当前位置: 首页 > news >正文

nodejs篇 express(1)

文章目录

    • 前言
    • express介绍
    • 安装
    • RESTful接口规范
    • express的简单使用
      • 一个最简单的服务器,仅仅只需要几行代码便可以实现。
      • restful规范的五种接口类型
      • 请求信息req的获取
      • 响应信息res的设置
      • 中间件的使用
      • 自定义中间件
      • 解决跨域
    • nodejs相关其它内容

前言

express作为nodejs必学的模块之一,从这篇文章开始,介绍express一些基础内容,express的安装,restful接口规范,express的接口开发,express的跨域处理,express的中间件使用,请求信息req常见处理,请求头res常见处理等。为接下来真正的项目框架下开发一个express服务器做准备。

express介绍

express是在nodejs内置模块http的基础上开发,也就是说http模块有的api,express全都有,并且它们的用法也很类似。

express.js的优点在于,它封装了一些常用的,接口处理方法,更有利于中间件的扩展,让接口的开发更加规范合理等。

安装

express不是nodejs的内置模块,属于第三方开源模块,想要使用需要下载安装。

将来要部署到服务器,在开发环境和生产环境都需要使用,输入命令行

npm install express --save 或者 yarn add express

在开发过程中,会发现,我们一直在编写服务端的代码,每次修改后,都需要关掉原来的服务器,重启 node express.js才能生效。

为此,再安装一个辅助npm包nodemon,nodemon能自动监听文件的更新,并自动重启。

npm install -g nodemon 或者 yarn global add nodemon 

安装好了之后,我们重启一下服务器,就再也不需要每次更改代码后都要重启了

nodemon express.js

RESTful接口规范

既然要开发服务器,我们就要遵循接口开发规范,这里简单介绍RESTful接口设计规范。

  1. 尽量使用https协议,如果条件不支持,就只能http协议
  2. 应该尽量将所有的api都放在专有域名之下,比如https://api.dengxi.com,当然,如果你的接口比较简单,业务也不复杂,你就可以 主域名 + '/api',比如网站的域名为http://dxyx-together.cn,那所有的api都放在http://dxyx-together.cn/api/xxx,后面的xxx就是api具体的path。
  3. 版本号,如果是专有域名 https://api.dengxi.com,当前版本为v1,那对应的就是https://api.dengxi.com/v1,如果不是专有域名,就将版本信息放在响应头中,这样可能不如直接放在url上直观。
  4. 路径名称,又称为终点endpoint,命名要求不允许出现英文的动词,而应该是名词复数。比如有一个接口返回许多用户的信息,就应该设计为xxx/api/users。如果返回的数据直接就是某个数据库表格的内容,那就直接以数据库表格名称命名即可。
  5. 常用的有五种接口get(获取数据),post(创建数据),delete(删除数据),put(完整更新数据),patch(某一数据部分更新),不常用的有两种(head,options),很多时候这几种接口类型可以混用,但按照规范,它们有属于自己的使用场景。
  6. 身份认证。部分接口涉及账户信息,比如常见的中后台管理系统,c端也有购物车、会员中心、钱包等场景,基于JWT的接口权限认证。
  7. 跨域处理,在服务端设置cors跨域处理,允许客户端跨域请求资源,特别是当接口放在专有域名下时。
  8. 每一个接口的每一次请求,服务器都必须给予http状态码回应和数据两个部分。
  9. http状态码分为五类 1xx(相关信息) 2xx(操作成功) 3xx(重定向) 4xx(客户端错误) 5xx(服务器错误)一共有一百多种状态码,常用的也就二十多种。
  10. 返回的数据部分,通常是JSON对象,因此,服务器返回头需要将Content-Type属性设置为application/json
  11. 错误处理主要是需要正确使用http状态码,主要是4xx和5xx,并且返回的信息尽可能详尽,以便更快速的排查。

express的简单使用

一个最简单的服务器,仅仅只需要几行代码便可以实现。

//express.js
var express = require("express");
var app = express();
var port = 3000;app.get("/", function (req, res) {res.send("hello world");
});app.listen(port, function () {console.log("server runing at 3000");
});

再输入命令行,服务器就成功启动

nodemon express.js

restful规范的五种接口类型

var express = require("express");
var app = express();
var port = 3000;app.get("/", function (req, res) {var query = req.queryconsole.log(query)res.send("hello world");
});app.post("/", function (req, res) {res.send("post hello world");
});app.put("/users",function(req,res) {res.send("put hello world");
})app.delete("/users",function(req,res) {res.send("delete hello world");
})app.patch("/users",function(req,res) {res.send("delete hello world");
})app.listen(port, function () {console.log("server runing at 3000");
});

请求信息req的获取

比如我们获取get请求的参数 req.query

//express.js
var express = require("express");
var app = express();
var port = 3000;app.get("/api", function (req, res) {console.log(req.query)res.status('200')
});app.listen(port, function () {console.log("server runing at 3000");
});

在这里插入图片描述
在这里插入图片描述
关于req的所有属性和方法,你可以在这里找到

http://expressjs.com/en/5x/api.html#req

中文版本的
http://expressjs.com/zh-cn/4x/api.html#req

响应信息res的设置

var express = require("express");
var app = express();
var port = 3000;app.get("/api", function (req, res) {var query = req.queryconsole.log(query)res.set('Content-Type', 'application/json')res.status('200')res.json({code:200,data: '请求成功了'})
});app.listen(port, function () {console.log("server runing at 3000");
});

在这里插入图片描述
在这里插入图片描述
关于res的所有属性和方法,你可以在这里找到
http://expressjs.com/en/5x/api.html#res

中文版本
http://expressjs.com/zh-cn/4x/api.html#res

中间件的使用

express官方提供了几个比较重要的中间件
http://expressjs.com/en/5x/api.html#express

比如express.json() ,当客户端发送的数据是json数据时,req.body是取不到正常的数据的,所以,我们需要通过这个中间件处理一下才可以。

我用http模块,来请求一下我express服务器

const http = require("http");// 请求刚刚创建的服务器
const options = {hostname: "localhost",port: 3000,path: "/api",method: "post",headers: {"Content-Type": "application/json",},
};const req = http.request(options, (res) => {console.log(`状态码: ${res.statusCode}`);console.log(`响应头: ${JSON.stringify(res.headers)}`);res.setEncoding("utf8");res.on("data", (chunk) => {console.log(`响应主体: ${chunk}`);});res.on("end", () => {console.log("响应中已无数据。");});
});
req.write(JSON.stringify({ name: "dx" })) // 发送了一个json数据
req.end();

通过app.use 来调用中间件,达到全局使用的目的

var express = require("express");
var app = express();
var port = 3000;app.use(express.json())app.post("/api", function (req, res) {console.log(req.body)res.set('Content-Type', 'application/json')res.status('200')res.json({code:200,data: '请求成功了'})
});app.listen(port, function () {console.log("server runing at 3000");
});

在这里插入图片描述
也可以在某个接口中单独使用中间件,只对这一个接口生效。

var express = require("express");
var app = express();
var port = 3000;// app.use(express.json())app.post("/api", express.json(), function (req, res) {// var query = req.queryconsole.log(req.body)res.set('Content-Type', 'application/json')res.status('200')res.json({code:200,data: '请求成功了'})
});app.listen(port, function () {console.log("server runing at 3000");
});

自定义中间件

中间件的本质,其实就是一个函数,express的中间件函数呢,有三个参数,req,res,next

创造一个中间件,用来打印日志,让每一次客户端请求的body都能在日志中看到,用来简化之前的方案。

function (req, res, next) {console.log(req.body);// 执行下一个中间件,必须调用,否则请求会被拦截在这里next();
}

再创造一个中间件,用来满足响应,总是返回status 200 并且返回相同的json

function (req, res, next) {res.set("Content-Type", "application/json");res.status("200");res.json({ code: 200, data: "请求成功了" });// 执行下一个中间件,必须调用,否则请求会被拦截在这里next();
}

使用这两个中间件

var express = require("express");
var app = express();
var port = 3000;app.use(express.json());app.use(function (req, res, next) {console.log(req.body);next();
});app.use(function (req, res, next) {res.set("Content-Type", "application/json");res.status("200");res.json({ code: 200, data: "请求成功了" });next();
});
// app.post 里面啥也没干
app.post("/api", express.json(), function (req, res) {
});app.listen(port, function () {console.log("server runing at 3000");
});

左边是服务器接口,打印了客户端传过来的name:dx,右边是客户端请求,同样拿到了状态码200和json数据。
在这里插入图片描述

中间件的执行顺序就是从上往下依次执行,执行的顺序也很重要。
如果是某一个单独的接口的中间件,中间件1比中间件2先执行性。

app.post("/api", 中间件1, 中间件2, function (req, res) {
});

解决跨域

一 用一种粗暴的方式,任意域名都能成功请求。

var express = require("express");
var app = express();
var port = 3000;//设置允许跨域访问该服务.
app.all("*", function (req, res, next) {res.header("Access-Control-Allow-Origin", "*"); // *表示所有域名,你也可以指定某个特别的域名 "www.dxyx-together.cn"res.header("Access-Control-Allow-Headers", "Content-Type");res.header("Access-Control-Allow-Methods", "*"); // *表示所有请求方式都可以跨域,你也可以设置 比如只允许get和post "GET;POST"res.header("Content-Type", "application/json;charset=utf-8"); next();
});app.use(express.json());app.use(function (req, res, next) {console.log(req.body);next();
});app.use(function (req, res, next) {res.set("Content-Type", "application/json");res.status("200");res.json({ code: 200, data: "请求成功了" });next();
});app.post("/api", express.json(), function (req, res) {});app.listen(port, function () {console.log("server runing at 3000");
});

二 express 的 cors跨域
cors 是 Express 的一个第三方中间件,通过安装和配置 cors 中间件,可以很方便地解决跨域问题
使用步骤分为三步

  1. 运行 npm install cors 安装中间件
  2. 使用 const cors = require('cors') 导入中间件
  3. 在路由之前调用 app.use(cors()) 配置中间件
var express = require("express");
var cors = require('cors')
var app = express();
var port = 3000;//设置允许跨域访问该服务.
app.use(cors())app.use(express.json());app.use(function (req, res, next) {console.log(req.body);next();
});app.use(function (req, res, next) {res.set("Content-Type", "application/json");res.status("200");res.json({ code: 200, data: "请求成功了" });next();
});app.post("/api", express.json(), function (req, res) {});app.listen(port, function () {console.log("server runing at 3000");
});

cors的更多使用方式,详见cors插件官方介绍
https://www.npmjs.com/package/cors

nodejs相关其它内容

nodejs commonjs介绍
nodejs fs模块介绍
nodejs path模块介绍
nodejs events模块介绍
nodejs http模块介绍
nodejs net模块介绍
nodejs url模块介绍
nodejs process模块介绍
nodejs buffer模块介绍
nodejs stream 模块介绍

相关文章:

nodejs篇 express(1)

文章目录前言express介绍安装RESTful接口规范express的简单使用一个最简单的服务器,仅仅只需要几行代码便可以实现。restful规范的五种接口类型请求信息req的获取响应信息res的设置中间件的使用自定义中间件解决跨域nodejs相关其它内容前言 express作为nodejs必学的…...

Java实习生------Redis常见面试题汇总(AOF持久化、RDB快照、分布式锁、缓存一致性)⭐⭐⭐

“年轻人,就要勇敢追梦”🌹 参考资料:图解redis 目录 谈谈你对AOF持久化的理解? redis的三种写回策略是什么? 谈谈你对AOF重写机制的理解?AOF重写机制的具体过程? 谈谈你对RDB快照的理解&a…...

seata服务搭建

它支持两种存储模式,一个是文件,一个是数据库,下面我们分别介绍一下这两种配置nacos存储配置,注意如果registry.conf中注册和配置使用的是file,就会去读取file.config的配置,如果是nacos则通过nacos动态读取…...

Kafka和RabbitMQ有哪些区别,各自适合什么场景?

目录标题1. 消息的顺序2. 消息的匹配3. 消息的超时4. 消息的保持5. 消息的错误处理6. 消息的吞吐量总结1. 消息的顺序 有这样一个需求:当订单状态变化的时候,把订单状态变化的消息发送给所有关心订单变化的系统。 订单会有创建成功、待付款、已支付、已…...

用Pytorch构建一个喵咪识别模型

本文参加新星计划人工智能(Pytorch)赛道:https://bbs.csdn.net/topics/613989052 目录 一、前言 二、问题阐述及理论流程 2.1问题阐述 2.2猫咪图片识别原理 三、用PyTorch 实现 3.1PyTorch介绍 3.2PyTorch 构建模型的五要素 3.3PyTorch 实现的步骤 3.3.…...

QT搭建MQTT开发环境

QT搭建MQTT开发环境 第一步、明确安装的QT版本 注意: 从QT5.15.0版本开始,官方不再提供离线版安装包,除非你充钱买商业版。 而在这里我使用的QT版本为5.15.2,在线安装了好久才弄好,还是建议使用离线安装的版本 在这里…...

Python3,5行代码,生成自动排序动图,这操作不比Excel香?

5行代码生成自动排序动图1、引言2、代码实战2.1 pynimate介绍2.2 pynimate安装2.3 代码示例3、总结1、引言 小屌丝:鱼哥,听说你的excel段位又提升了? 小鱼:你这是疑问的语气? 小屌丝:没有~ 吧… 小鱼&…...

【Java SE】变量的本质

目录一. 前言二. 变量(variable)2.1 性质2.2 变量类型2.2.1 核心区别2.3 变量的使用三. 总结一. 前言 一天一个Java小知识点,助力小伙伴更好地入门Java,掌握更深层次的语法。 二. 变量(variable) 2.1 性质 变量本质上就是代表一个”可操作的存储空间”…...

【Android笔记85】Android之使用Camera和MediaRecorder录制视频

这篇文章,主要介绍Android之使用Camera和MediaRecorder录制视频。 目录 一、录制视频 1.1、案例运行效果 1.2、创建Camera对象 1.3、创建MediaRecorder对象...

MySQL集群搭建与高可用性实现:掌握主从复制、多主复制、负载均衡和故障切换技术,让你的MySQL数据库永不宕机!

MySQL集群和高可用性MySQL是一款广泛使用的关系型数据库管理系统,常用于Web应用和企业级应用中。为了提高MySQL的可用性,我们可以通过搭建MySQL集群和实现高可用性来保障数据的稳定性和可靠性。本文将介绍如何搭建MySQL集群和实现高可用性,包…...

收到6家大厂offer,我把问烂了的《Java八股文》打造成3个文档。共1700页!!

前言大家好,最近有不少小伙伴在后台留言,近期的面试越来越难了,要背的八股文越来越多了,考察得越来越细,越来越底层,明摆着就是想让我们徒手造航母嘛!实在是太为难我们这些程序员了。这不&#…...

多线程 (六) 单例模式

🎉🎉🎉点进来你就是我的人了 博主主页:🙈🙈🙈戳一戳,欢迎大佬指点!人生格言:当你的才华撑不起你的野心的时候,你就应该静下心来学习! 欢迎志同道合的朋友一起加油喔🦾&am…...

Docker入门到放弃笔记之容器

1、启动容器1.1容器hello world1.2 容器bash终端1.3 后台运行容器是 Docker 三大核心概念之一,其余两个是镜像与仓库。本文主讲容器。简单的说,容器是独立运行的一个或一组应用,以及它们的运行态环境。对应的,虚拟机可以理解为模拟…...

项目二 任务三 训练5 交换机的HSRP技术

在“项目二 任务三 训练4 交换机的DHCP技术”基础上继续完成下列操作: 1、二层交换机50-2的配置 50-2>en 50-2#conf t Enter configuration commands, one per line. End with CNTL/Z. 50-2(config)#int 50-2(config)#interface g 50-2(config)#interface gigab…...

计算机网络复习重点

文章目录计算机网络复习重点第一章 计算机网络和因特网概念与应用1、什么是因特网2、协议protocol3、入网方式4、物理媒介5、数据交换模式6、延时与丢包什么时候发生延时?延时的类型丢包何时发生7、协议层次与模型因特网协议栈TCP / IP模型ISO/OSI参考模型协议数据单…...

算法基础---基础算法

文章目录 快速排序归并排序二分 整数二分浮点数二分高精度 高精度加法高精度减法高精度乘法高精度除法前缀和 一维前缀和二维前缀和差分 一维差分二维差分双指针位运算离散化区间合并一、快速排序 思想:1.首先确定一个分界点(随机取任意一点为…...

linux中写定时任务

场景:我们生产环境中有大量的日志记录,但是我们的磁盘没有太大,需要定时清理磁盘 文章目录crond 定时任务详解安装定时任务crontab服务启动与关闭crontab操作crontab 命令test.sh查看日志丢弃linux中的执行日志Linux进入nano模式方式一方式二…...

2023.3.21

6&#xff1a;有序数组中找到num // arr保证有序&#xff0c;在arr数组中寻找num&#xff0c;二分查找public static boolean find(int[] arr, int num) {if(arr null || arr.length 0) {return false;}int L 0;int R arr.length - 1;while (L < R) {int mid (L R) /…...

制作数据库框架

一 利用前端条件组装sql与查询条件的集合public void handle() throws Exception{Map<String,String> requestMap new HashMap();String fromdate requestMap.get("fromdate");String todate requestMap.get("todate");String resultcode reque…...

Winbond W25Qxx SPI FLASH 使用示例(基于沁恒CH32V307单片机)

文章目录目的基础说明使用示例总结目的 Winbond&#xff08;华邦&#xff09;的 W25Qxx 系列 SPI FLASH 是比较常用的芯片&#xff0c;这篇文章将演示单片机中通过SPI使用该芯片的操作过程。 本文使用沁恒官方的开发板 &#xff08;CH32V307-EVT-R1沁恒RISC-V模块MCU赤兔评估…...

生成xcframework

打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式&#xff0c;可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?

大家好&#xff0c;欢迎来到《云原生核心技术》系列的第七篇&#xff01; 在上一篇&#xff0c;我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在&#xff0c;我们就像一个拥有了一块崭新数字土地的农场主&#xff0c;是时…...

uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖

在前面的练习中&#xff0c;每个页面需要使用ref&#xff0c;onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入&#xff0c;需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

ffmpeg(四):滤镜命令

FFmpeg 的滤镜命令是用于音视频处理中的强大工具&#xff0c;可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下&#xff1a; ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜&#xff1a; ffmpeg…...

【论文笔记】若干矿井粉尘检测算法概述

总的来说&#xff0c;传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度&#xff0c;通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...

Nginx server_name 配置说明

Nginx 是一个高性能的反向代理和负载均衡服务器&#xff0c;其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机&#xff08;Virtual Host&#xff09;。 1. 简介 Nginx 使用 server_name 指令来确定…...

稳定币的深度剖析与展望

一、引言 在当今数字化浪潮席卷全球的时代&#xff0c;加密货币作为一种新兴的金融现象&#xff0c;正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而&#xff0c;加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下&#xff0c;稳定…...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题

分区配置 (ptab.json) img 属性介绍&#xff1a; img 属性指定分区存放的 image 名称&#xff0c;指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件&#xff0c;则以 proj_name:binary_name 格式指定文件名&#xff0c; proj_name 为工程 名&…...

在Ubuntu24上采用Wine打开SourceInsight

1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...