nodejs入门(1):nodejs的前后端分离
一、引言
我关注nodejs还是从前几年做了的一个电力大数据展示系统开始的,当然,我肯定是很多年的计算机基础的,万变不离其宗。
现在web网站都流行所谓的前后端结构,不知不觉我也开始受到这个影响,以前都是前端直接操作ODBC、ADO等链接到数据库,不分什么前端后端的。现在大家都讲究了,一个后端web服务器来处理后台的数据库,格式化输出前端请求的数据;浏览器和前端web服务器交互,前端web服务器和后端web服务器进行交互,前端web服务器向后端的web服务器请求数据,对后端服务器得到请求后将数据传递给前端web服务器,格式化后由浏览器展示。

当然,这里是将前后端严格分离的一种状态。
二、案例
我们将按照前后端分离的要求,将项目分为两个目录:`server` 和 `client`。`server` 目录将包含后端代码,使用端口3000;`client` 目录将包含前端代码,使用端口80。以下是案例:
1、项目结构
my-web-app/
|-- server/
| |-- node_modules/
| |-- package.json
| `-- app.js
`-- client/|-- node_modules/|-- package.json|-- public/| |-- index.html| `-- script.js`-- server.js
2、 后端 (server/app.js)
1).初始化后端项目:
在 `server` 目录中运行以下命令来初始化项目:
npm init -y
npm install express body-parser
2)创建后端服务器:
在 `server` 目录中创建 `app.js` 文件,并添加以下代码:
const express = require('express');const bodyParser = require('body-parser');const app = express();const port = 3000;// 用于解析JSON格式的请求体app.use(bodyParser.json());// 用于解析application/x-www-form-urlencoded格式的请求体app.use(bodyParser.urlencoded({ extended: true }));// API路由app.get('/api/data', (req, res) => {res.json({ message: 'Hello from the server!' });});// 启动服务器app.listen(port, () => {console.log(`Server running on port ${port}`);});
3、 前端 (client)
1).初始化前端项目:
在 `client` 目录中运行以下命令来初始化项目:
npm init -y
npm install express
2).创建前端服务器:
在 `client` 目录中创建 `server.js` 文件,并添加以下代码:
const express = require('express');const app = express();const port = 80;// 静态文件服务app.use(express.static('public'));// 启动服务器app.listen(port, () => {console.log(`Client server running on port ${port}`);});
3)创建静态文件:
在 `client` 目录中创建 `public` 文件夹,并在其中创建 `index.html` 和 `script.js` 文件。 - public/index.html:
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Simple Web App</title></head><body><h1>Simple Web App</h1><button id="fetchData">Fetch Data from Server</button><p id="data"></p><script src="script.js"></script></body></html>
public/script.js:
-
document.getElementById('fetchData').addEventListener('click', function() {fetch('http://localhost:3000/api/data').then(response => response.json()).then(data => {document.getElementById('data').textContent = data.message;}).catch(error => console.error('Error:', error)); });
4、运行项目
1)启动后端服务器: 在 server 目录下运行以下命令来启动后端服务器:
node app.js
2)启动前端服务器:
在 client 目录下运行以下命令来启动前端服务器:
npm run client
3)访问应用:
打开浏览器并访问 http://localhost,你将看到“Simple Web App”的标题和一个按钮。点击按钮,页面将通过JavaScript从后端API获取数据,并在页面上显示。
这样,我们就创建了一个简单的前后端分离的Web应用,其中后端使用Node.js和Express框架提供API,前端使用HTML和JavaScript来请求数据并显示在页面上。
三、nodejs简介
Node.js是一个开源且跨平台的JavaScript运行时环境,它几乎适用于任何类型的项目!
Node.js运行V8 JavaScript引擎,这是Google Chrome的核心,但脱离了浏览器环境。这使得Node.js性能非常出色。
Node.js应用在一个单一进程中运行,不会为每个请求创建新线程。Node.js在其标准库中提供了一组异步I/O原语,这些原语阻止了JavaScript代码的阻塞行为,通常,Node.js中的库都是使用非阻塞范式编写的,使得阻塞行为成为例外而非常态。
当Node.js执行I/O操作时,比如从网络读取、访问数据库或文件系统,它不会阻塞线程并浪费CPU周期等待,而是在响应回来时恢复操作。
这使得Node.js能够用单个服务器处理成千上万的并发连接,而不需要引入管理线程并发的负担,这可能是产生错误的一个重要源头。
Node.js有一个独特的优势,因为数百万为浏览器编写JavaScript的前端开发者现在也能够编写服务器端代码,而不需要学习完全不同的语言。
在Node.js中,可以无障碍地使用新的ECMAScript标准,因为你不需要等待所有用户更新他们的浏览器——你可以通过更改Node.js版本来决定使用哪个ECMAScript版本,也可以通过运行带有标志的Node.js来启用特定的实验性功能。
一个Node.js应用示例
Node.js最常见的示例“Hello World”是一个Web服务器:
const { createServer } = require('node:http');
const hostname = '127.0.0.1';
const port = 3000;
const server = createServer((req, res) => {res.statusCode = 200;res.setHeader('Content-Type', 'text/plain');res.end('Hello World');
});
server.listen(port, hostname, () => {console.log(`Server running at http://${hostname}:${port}/`);
});
要运行这段代码,请将其保存为server.js文件,并在终端中运行node server.js。
- 这段代码首先引入了Node.js的http模块。
- Node.js拥有一个出色的标准库,包括对网络的一级支持。
- http的createServer()方法创建了一个新的HTTP服务器并返回它。
- 服务器被设置为监听指定的端口和主机名。当服务器准备好时,回调函数被调用,在这种情况下是通知我们服务器正在运行。
- 每当收到新的请求时,会触发请求事件,提供两个对象:一个请求(一个http.IncomingMessage对象)和一个响应(一个http.ServerResponse对象)。
- 这两个对象对于处理HTTP调用至关重要。
- 第一个对象提供了请求详情。在这个简单的例子中,这个对象没有被使用,但你可以通过它访问请求头和请求数据。
- 第二个对象用于向调用者返回数据。
在这个例子中:
res.statusCode = 200;
我们将statusCode属性设置为200,表示成功响应。
我们设置Content-Type头部:
res.setHeader('Content-Type', 'text/plain');
然后我们结束响应,在end()方法的参数中添加内容:
res.end('Hello World\n');
四、几个常见的概念
在基于Node.js的应用中,前端、后端、router(路由器)、API接口、AJAX各自扮演着不同的角色,并且它们之间有着紧密的联系。下面我将解释每个概念的作用,并举例说明它们是如何相互联系的。
1. 前端(Frontend)
作用:前端指的是用户直接与之交互的应用程序部分,通常是通过Web浏览器访问的。它负责展示用户界面(UI)和用户体验(UX)。
在Node.js中:虽然Node.js主要用于后端开发,但你可以利用Node.js的http模块或express框架来提供前端资源(如HTML、CSS、JavaScript文件),或者作为前端构建工具(如Webpack)的服务器。
举例:在一个基于Node.js的电商网站中,前端页面会展示商品列表、购物车、用户登录界面等。
2. 后端(Backend)
作用:后端是指服务器端的应用程序,处理业务逻辑、数据库交互、身份验证等。它为前端提供API接口,处理前端发送的请求,并返回数据。
在Node.js中:Node.js作为后端平台,使用JavaScript来编写服务器端代码。你可以使用Express框架来简化HTTP请求的处理。
举例:在上述电商网站中,后端会处理用户登录、商品信息的检索、订单处理等。
3. Router(路由器)
- 定义:在Web开发中,
router通常指的是一个组件或服务,它负责根据请求的URL和HTTP方法(如GET、POST等)将请求路由到相应的处理函数或控制器。 - 作用:
router的主要作用是决定如何处理进入应用的请求,并将其分发到正确的处理逻辑。 - 位置:在前端框架中(如React Router、Vue Router),
router用于控制页面路由和导航。在后端框架中(如Express中的路由器),它用于处理服务器端的请求路由。 - 举例:在Express中,你可能会有如下的路由定义:
app.get('/api/users', function(req, res) {res.send('用户列表'); });
4. API接口
- 定义:API接口(Application Programming Interface)是指一组预定义的函数、协议和工具,用于构建软件应用。在Web开发中,API接口通常指的是后端系统对外提供服务的端点(Endpoint)。
- 作用:API接口允许不同的软件应用之间进行交互,它定义了请求的格式、预期的响应以及可能的错误代码。它使得前端应用能够与后端服务进行通信。
- 位置:API接口是后端系统的一部分,它们定义了后端服务的功能和数据交换的规则。
- 举例:一个RESTful API接口可能看起来像这样:
GET /api/users => 获取用户列表 POST /api/users => 创建新用户 PUT /api/users/:id => 更新指定ID的用户 DELETE /api/users/:id => 删除指定ID的用户
5. Router和API接口的关系
- 联系:在后端应用中,
router用于定义API接口的路由规则,即哪个URL对应哪个API接口。router处理的是HTTP请求的分发,而API接口定义了请求和响应的具体格式。 - 区别:
router关注的是请求如何被分配到不同的处理函数,而API接口关注的是如何处理这些请求以及如何响应。 - 协同工作:在实际应用中,
router和API接口是协同工作的。router根据请求的URL和方法将请求路由到对应的API接口处理函数,然后API接口执行具体的业务逻辑,并返回相应的数据。
6. AJAX
作用:AJAX(Asynchronous JavaScript and XML)是一种在无需重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术。
在Node.js中:虽然AJAX主要在客户端使用,但在基于Node.js的应用中,AJAX请求会被后端的Express应用接收和处理。Node.js后端可以响应这些异步请求,并返回JSON或XML数据。
举例:在电商网站的购物车页面,用户可以点击一个按钮来更新购物车中的商品数量。这个按钮的点击事件会触发一个AJAX请求到后端的/api/cart/update路由,后端处理这个请求并更新数据库中的购物车信息,然后返回更新后的结果。
7. 相互联系
在一个基于Node.js的Web应用中,前端通过AJAX与后端通信,后端使用router来处理这些AJAX请求。以下是它们的工作流程:
- 用户交互:用户在前端页面上进行操作,如点击按钮或提交表单。
- AJAX请求:前端JavaScript捕获这些操作并发起AJAX请求到后端。
- 路由处理:后端的Express应用使用router来接收AJAX请求,并根据请求的URL和方法将请求路由到相应的处理函数。
- 业务逻辑:后端处理函数执行业务逻辑,如查询数据库或执行计算。
- 响应返回:后端将处理结果以JSON或XML的形式返回给前端。
- 页面更新:前端接收到后端的响应后,使用JavaScript更新页面的相应部分,而不需要重新加载整个页面。
这个流程展示了前端、后端、router和AJAX如何在基于Node.js的应用中协同工作,以提供流畅的用户体验。
五、练习
1.下载nodejs:Node.js — 在任何地方运行 JavaScript
2. 安装完毕后,在终端中输入:node -v, 能显示正确的版本,表示安装成功。
3. 安装npm中文镜像cnpm: npm install -g cnpm --registry=https://registry.npm.taobao.org
4. 如果更新或者安装包出现证书失效,可以临时绕过 SSL 验证:
npm config set strict-ssl false
5. 在一个新的目录下新建一个nodejs项目,使用: npm init。并创建一个package.json文件。这个文件记录了项目的元数据和配置信息,包括项目的依赖关系、脚本、版本号等。 npm init 会提示你输入一些信息,包括项目名称、版本、描述、入口点、测试命令等。对于一个名为 "test" 的项目,你可能需要回答以下问题:
name: (默认是当前目录的名字)testversion: (默认是1.0.0)description: 你的项目描述entry point: (默认是index.js)test command: 测试脚本命令git repository: git 仓库地址keywords: 关键词author: 作者信息license: 许可证类型
你可以按回车键接受默认值,或者输入新的值。
6. 安装一个新矿建express.js: npm install express。
7.完成第2部分的案例,并执行出来。
相关文章:
nodejs入门(1):nodejs的前后端分离
一、引言 我关注nodejs还是从前几年做了的一个电力大数据展示系统开始的,当然,我肯定是很多年的计算机基础的,万变不离其宗。 现在web网站都流行所谓的前后端结构,不知不觉我也开始受到这个影响,以前都是前端直接操作…...
笔记|M芯片MAC (arm64) docker上使用 export / import / commit 构建amd64镜像
很简单的起因,我的东西最终需要跑在amd64上,但是因为mac的架构师arm64,所以直接构建好的代码是没办法跨平台运行的。直接在arm64上pull下来的docker镜像也都是arm64架构。 检查镜像架构: docker inspect 8135f475e221 | grep Arc…...
gorm框架
连接 需要下载mysql的驱动 go get gorm.io/driver/mysql go get gorm.io/gorm 约定 主键:GORM 使用一个名为ID 的字段作为每个模型的默认主键。表名:默认情况下,GORM 将结构体名称转换为 snake_case 并为表名加上复数形式。 例如…...
免费送源码:Java+Springboot+MySQL Springboot多租户博客网站的设计 计算机毕业设计原创定制
Springboot多租户博客网站的设计 摘 要 博客网站是当今网络的热点,博客技术的出现使得每个人可以零成本、零维护地创建自己的网络媒体,Blog站点所形成的网状结构促成了不同于以往社区的Blog文化,Blog技术缔造了“博客”文化。本文课题研究的“…...
【ASR技术】WhisperX安装使用
介绍 WhisperX 是一个开源的自动语音识别(ASR)项目,由 m-bain 开发。该项目基于 OpenAI 的 Whisper 模型,通过引入批量推理、强制音素对齐和语音活动检测等技术。提供快速自动语音识别(large-v2 为 70 倍实时…...
【计算机网络】协议定制
一、结构化数据传输流程 这里涉及协议定制、序列化/反序列化的知识 对于序列化和反序列化,有现成的解决方案:①json ②probuff ③xml 二、理解发送接收函数 我们调用的所有发送/接收函数,根本就不是把数据发送到网络中!本质都是…...
【SQL】mysql常用命令
为方便查询,特整理MySQL常用命令。 约定:$后为Shell环境命令,>后为MySQL命令。 1 常用命令 第一步,连接数据库。 $ mysql -u root -p # 进入MySQL bin目录后执行,回车后输入密码连接。# 常用参数&…...
阿里云引领智算集群网络架构的新一轮变革
阿里云引领智算集群网络架构的新一轮变革 云布道师 11 月 8 日~ 10 日在江苏张家港召开的 CCF ChinaNet(即中国网络大会)上,众多院士、教授和业界技术领袖齐聚一堂,畅谈网络未来的发展方向,聚焦智算集群网络的创新变…...
几何合理的分片段感知的3D分子生成 FragGen - 评测
FragGen 来源于 2024 年 3 月 25 日 预印本的文章,文章题目是 Deep Geometry Handling and Fragment-wise Molecular 3D Graph Generation, 作者是 Odin Zhang,侯廷军,浙江大学药学院。FragGen 是一个基于分子片段的 3D 分子生成模…...
Python爬虫下载新闻,Flask展现新闻(2)
上篇讲了用Python从新闻网站上下载新闻,本篇讲用Flask展现新闻。关于Flask安装网上好多教程,不赘述。下面主要讲 HTML-Flask-数据 的关系。 简洁版 如图,页面简单,主要显示新闻标题。 分页,使用最简单的分页技术&…...
监控易监测对象及指标之:全面监控华为FusionInsight服务
随着大数据技术的广泛应用,华为FusionInsight以其卓越的性能和稳定性,成为了众多企业处理和分析海量数据的首选平台。然而,为了确保FusionInsight服务的持续稳定运行,对其进行全面监控至关重要。本文基于监控易工具,对…...
SQL面试题——蚂蚁SQL面试题 会话分组问题
会话分组问题 这里的分组不是简单的分组,而是会话的分组。 比如说,进入一个网站以后,可以连续的点击很多个页面,后台会记录用户的行为日志; 如果T日上午连续点击几个页面后退出了网站,直到第二天的下午才再次进入网站,单单从时间线上来看,昨天退出的那条日志跟今天进…...
nfs服务器--RHCE
一,简介 NFS(Network File System,网络文件系统)是FreeBSD支持的文件系统中的一种,它允许网络中的计 算机(不同的计算机、不同的操作系统)之间通过TCP/IP网络共享资源,主要在unix系…...
React--》如何高效管理前端环境变量:开发与生产环境配置详解
在前端开发中,如何让项目在不同环境下表现得更为灵活与高效,是每个开发者必须面对的挑战,从开发阶段的调试到生产环境的优化,环境变量配置无疑是其中的关键。 env配置文件:通常用于管理项目的环境变量,环境…...
Javascript高级—函数柯西化
函数柯西化(经典面试题) // 实现一个add方法,使计算结果能够满足如下预期: add(1)(2)(3) 6; add(1, 2, 3)(4) 10; add(1)(2)(3)(4)(5) 15;function add() {// 第一次执行时,定义一个数组专门用来存储所有的参数var…...
Sql进阶:字段中包含CSV,如何通过Sql解析CSV成多行多列?
Sql进阶 一、问题描述二、解决思路<一>、拆成多行<二>、拆成多列 三、代码实现 一、问题描述 Oracle数据库中某个字段value是CLOB类型,存的是csv格式的数据,如下所示 classnovalue1name,age,sex,… ‘李世民’,20,‘M’,…’ ‘李治’,18,‘M’,… ‘武则天’,16…...
linux之调度管理(5)-实时调度器
一、概述 在Linux内核中,实时进程总是比普通进程的优先级要高,实时进程的调度是由Real Time Scheduler(RT调度器)来管理,而普通进程由CFS调度器来管理。 实时进程支持的调度策略为:SCHED_FIFO和SCHED_RR。 SCHED_FIFOÿ…...
mybatis-plus: mapper-locations: “classpath*:/mapper/**/*.xml“配置!!!解释
和mybatis一样的道理!!!!如果不指定这个配置,通常要求 XML 映射文件和 Mapper 接口的包名和结构相同!!!! 如果没有配置 mapper-locations,通常文件结构应遵循…...
nacos-operator在k8s集群上部署nacos-server2.4.3版本踩坑实录
文章目录 操作步骤1. 拉取仓库代码2. 安装nacos-operator3. 安装nacos-server 坑点一坑点二nacos-ui页面访问同一集群环境下微服务连接nacos地址配置待办参考文档 操作步骤 1. 拉取仓库代码 (这一步主要用到代码中的相关yml文件,稍加修改用于部署容器&…...
面试篇-项目管理
⼀、构建管理 项目为什么选择Maven构建? 选择Maven进行项目构建有以下几个主要原因: 1. 依赖管理:Maven 提供了强大的依赖管理功能,可以自动下载项目所需的第三方库和依赖,并且可以管理这些依赖的版本、范围等信息。这简化了项…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...
TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...
.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
循环冗余码校验CRC码 算法步骤+详细实例计算
通信过程:(白话解释) 我们将原始待发送的消息称为 M M M,依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)(意思就是 G ( x ) G(x) G(x) 是已知的)࿰…...
CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...
STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...
linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
