Node.js基础与应用

目录

1.要求

2.创建第一个Node.js代码

2.1 安装 VSCode 和所需插件

2.2 安装 Node.js 和 Yarn

2.3 创建 Node.js 项目

2.3.1 在 VSCode 中打开一个新文件夹

2.3.2 初始化 Node.js 项目

2.3.3 安装 Express

2.4 编写 Node.js 应用

2.4.1 创建主文件

2.4.2 运行应用

2.5 使用 Parcel 自动化开发 (可选)

2.4.1 项目结构

2.5.2 安装 Parcel

2.5.3 配置 Parcel

2.5.4 启动 Parcel

2.6 简述

3.REPL、回调函数、事件循环

3.1 REPL(Read-Eval-Print Loop)

3.1.1 代码示例:

3.1.2 简述:

3.2 回调函数(Callback Function)

3.2.1 代码示例:

​编辑

3.2.2 简述:

3.3 事件循环(Event Loop)

3.3.1 代码示例:

​编辑

3.3.2 简述:

3.4 总结

4. 内容 9-26

4.1 Node.js EventEmitter

4.1.1 用途及能做什么:

4.1.2 解决的问题:

4.1.3代码示例:

4.1.4 代码解释:

4.2 Node.js Buffer

4.2.1 用途及能做什么:

4.2.2 解决的问题:

4.2.3 代码示例:

4.2.4 代码解释:

4.3 Node.js Stream

4.3.1 用途及能做什么:

4.3.2 解决的问题:

4.3.3 代码示例:

4.3.4 代码解释:

4.4 Node.js 模块系统

4.4.1 用途及能做什么:

4.4.2 解决的问题:

4.4.3 代码示例:

代码解释:

4.5 Node.js 路由

4.5.1 用途及能做什么:

4.5.2 解决的问题:

4.5.3 代码示例:

4.5.4 代码解释:

4.6 Node.js 全局对象

4.6.1 用途及能做什么:

4.6.2 解决的问题:

4.6.3 代码示例:

4.6.3 代码解释:

4.7 Node.js RESTful API

4.7.1 用途及能做什么:

4.7.2 解决的问题:

4.7.3 代码示例:

4.7.4 代码解释:

4.8 Node.js 文件系统

4.8.1 用途及能做什么:

4.8.2 解决的问题:

4.8.3 代码示例:

4.8.4 代码解释:

4.9 Node.js GET/POST 请求

4.9.1 用途及能做什么:

4.9.2 解决的问题:

4.9.3 代码示例:

4.9.4 代码解释:

4.10 Node.js 工具模块

4.10.1 用途及能做什么:

4.10.2 解决的问题:

4.10.3 代码示例:

4.10.4 代码解释:

4.11 Node.js Web 模块

4.11.1 用途及能做什么:

4.11.2 解决的问题:

4.11.3 代码示例:

4.11.4 代码解释:

4.12 Node.js Express 框架

4.12.1 用途及能做什么:

4.12.2 解决的问题:

4.12.3 代码示例:

4.12.4 代码解释:

4.13 Node.js 多进程

4.13.1 用途及能做什么:

4.13.2 解决的问题:

4.13.3 代码示例:

4.13.4 代码解释:

4.14 Node.js MySQL

4.14.1 用途及能做什么:

4.14.2 解决的问题:

4.14.3 代码示例:

4.14.4 代码解释:

4.15 Node.js MongoDB

4.15.1 用途及能做什么:

4.15.2 解决的问题:

4.15.3 代码示例:

4.15.4 代码解释:

5.基于 Node.js 和 MySQL 的简易 CMS 系统开发

步骤 1:创建项目结构

步骤 2:安装依赖

步骤 3:配置 MySQL 数据库连接

创建 config/database.js

步骤 4:创建模型文件 models/article.js

步骤 5:创建路由文件 routes/articles.js

步骤 6:创建主应用文件 app.js

步骤 7:创建模板文件

views/index.ejs

views/articles/new.ejs

views/articles/show.ejs

views/articles/edit.ejs

步骤 8:启动应用

步骤9:查看


1.要求

1. 安装好node、parcel、yarn和VSCode及插件Fitten Code等工具,复习Node.js创建第一个应用,代码和简述写入实验报告
2. 根据 https://www.runoob.com/nodejs/nodejs-tutorial.html 学习REPL,回调函数、事件循环,代码和简述写入实验报告
3. 内容9-20,自选3个的代码和简述写入实验报告
4. 内容21-26,自选3个的代码和简述写入实验报告
5. 百度里输入 “node.js写一个简单CMS”根据提示完成调试,记录过程并写入实验报告


2.创建第一个Node.js代码

2.1 安装 VSCode 和所需插件

  • 下载并安装 VSCode。
  • 打开 VSCode 后,建议安装以下插件:
    • Fitten Code:代码优化工具。
    • ESLint:JavaScript 代码检查工具。
    • Prettier:代码格式化工具。

2.2 安装 Node.js 和 Yarn

  • 安装 Node.js,可以使用默认设置完成安装。安装完成后,您可以在终端中输入 node -v,确保安装成功。

  • 安装 Yarn 包管理工具,使用以下命令:

    npm install -g yarn

2.3 创建 Node.js 项目

2.3.1 在 VSCode 中打开一个新文件夹

  • 点击 "File" -> "Open Folder...",选择一个空文件夹,作为项目的根目录。

2.3.2 初始化 Node.js 项目

  • 打开 VSCode 的终端(可以通过菜单栏中的 "Terminal" -> "New Terminal" 来打开),输入以下命令来初始化一个新的项目:

    yarn init -y

  • 这会生成一个 package.json 文件,用于管理项目的依赖项。

2.3.3 安装 Express

  • 在终端中输入以下命令来安装 Express.js 作为 Web 框架:

    yarn add express

2.4 编写 Node.js 应用

2.4.1 创建主文件

  • 在项目根目录下,创建一个名为 app.js 的文件,编写以下代码:
    const express = require('express');
    const app = express();app.get('/', (req, res) => {res.send('Hello, Node.js!');
    });const port = 3000;
    app.listen(port, () => {console.log(`Server is running at http://localhost:${port}`);
    });
    

2.4.2 运行应用

  • 在 VSCode 终端中运行以下命令启动 Node.js 应用:

    node app.js

  • 您将在终端中看到提示 Server is running at http://localhost:3000。现在,您可以在浏览器中访问 http://localhost:3000,会看到页面显示 Hello, Node.js from VSCode!

2.5 使用 Parcel 自动化开发 (可选,做了解)

如果希望更方便地进行开发,可以使用 Parcel 来自动刷新页面。

2.4.1 项目结构

project-root/

├── app.js  (服务器端代码,注意前面的是服务端)
├── public/  (存放前端文件)
│   ├── index.html  (前端 HTML 文件)
│   └── app.js  (前端 JavaScript 文件)
└── node_modules/  (依赖包)

2.5.2 安装 Parcel

  • 在 VSCode 终端中输入:

    yarn global add parcel-bundler

2.5.3 配置 Parcel

  • 在项目目录下创建一个 index.html 文件,内容如下:
    <!DOCTYPE html>
    <html lang="en">
    <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Node.js with Parcel</title>
    </head>
    <body><script src="./app.js"></script>
    </body>
    </html>
    

2.5.4 启动 Parcel

Parcel 会自动打包文件并在浏览器中显示结果,您无需每次手动刷新页面。

  • 在终端中使用以下命令启动 Parcel 进行开发:

    parcel index.html

2.6 简述

通过使用 VSCode 创建并运行 Node.js 应用,我们能够快速搭建一个 Web 服务。整个过程涵盖了环境配置、项目初始化、开发工具安装和调试等核心步骤。


3.REPL、回调函数、事件循环

3.1 REPL(Read-Eval-Print Loop)

REPL 是 Node.js 提供的一个交互式环境,用于执行 JavaScript 代码。

3.1.1 代码示例:

$ node
> const x = 10;
> const y = 20;
> x + y
30

3.1.2 简述:

  • Read:读取用户输入。
  • Eval:执行输入的代码。
  • Print:打印执行结果。
  • Loop:等待用户输入新的指令。

REPL 常用于测试小段代码或简单逻辑。

3.2 回调函数(Callback Function)

3.2.1 代码示例:

const fs = require('fs');fs.readFile('example.txt', 'utf8', (err, data) => {if (err) {return console.error(err);}console.log('文件内容:', data);
});

3.2.2 简述:

  • 回调函数是一种异步编程的实现方式,它作为参数传递给另一个函数,并在操作完成时调用。
  • 上述代码展示了如何使用 fs.readFile() 异步读取文件。当文件读取完成后,Node.js 会调用提供的回调函数,并传入读取结果或错误信息。

3.3 事件循环(Event Loop)

3.3.1 代码示例:

console.log('Start');setTimeout(() => {console.log('Timeout');
}, 1000);console.log('End');

3.3.2 简述:

  • 事件循环是 Node.js 处理异步操作的机制。JavaScript 本身是单线程的,但事件循环允许它管理异步任务,如 I/O 操作、计时器等。
  • 在上述代码中,console.log('Start')console.log('End') 会立即执行。而 setTimeout() 设定的回调函数则会在 1 秒后通过事件循环执行。

3.4 总结

  • REPL 是一个快速测试 JavaScript 代码的交互环境。
  • 回调函数 是 Node.js 中处理异步操作的核心,通过将函数作为参数传递来实现任务的延迟执行。
  • 事件循环 则确保异步代码按顺序执行,并避免阻塞主线程。

4. 内容 9-26

4.1 Node.js EventEmitter

4.1.1 用途及能做什么:

  • 实现 事件驱动编程,在应用程序中基于事件来触发逻辑执行。
  • 适用于 用户操作反馈资源加载完成事件异步任务完成后的通知

4.1.2 解决的问题:

  • 解耦逻辑:将复杂逻辑拆分成多个事件处理程序,提高代码灵活性和可维护性。

4.1.3代码示例:

const events = require('events'); // 引入事件模块
const eventEmitter = new events.EventEmitter(); // 创建事件发射器// 监听事件 'message',并定义事件触发时的回调
eventEmitter.on('message', (msg) => {console.log(`收到消息: ${msg}`);
});// 触发 'message' 事件,并传递消息
eventEmitter.emit('message', '你好,Node.js!');

4.1.4 代码解释:

  1. require('events'):引入 Node.js 的事件模块。
  2. new EventEmitter():创建一个事件发射器实例。
  3. .on():监听特定事件并绑定回调函数。
  4. .emit():触发事件,并将参数传递给事件处理函数。

4.2 Node.js Buffer

4.2.1 用途及能做什么:

  • 处理 二进制数据,适用于文件、图片、音频和视频流等。
  • 在网络传输时,数据通常以二进制形式传递,Buffer 是处理这些数据的核心工具。

4.2.2 解决的问题:

  • JavaScript 不支持直接操作二进制数据,Buffer 让你可以处理二进制文件和网络数据流。

4.2.3 代码示例:

const buffer = Buffer.from('Hello, Buffer!'); // 将字符串转换为 Buffer
console.log('Buffer 内容:', buffer); // 打印 Buffer 数据
console.log('转换为字符串:', buffer.toString()); // 将 Buffer 转换回字符串

4.2.4 代码解释:

  1. Buffer.from():将字符串转换为二进制 Buffer 数据。
  2. console.log():输出 Buffer 数据,显示其内容。
  3. .toString():将 Buffer 还原为可读的字符串。

4.3 Node.js Stream

4.3.1 用途及能做什么:

  • 处理大文件和实时数据流,避免一次性加载所有数据到内存中。
  • 常用于文件读写、网络请求和媒体流传输。

4.3.2 解决的问题:

  • 避免内存耗尽:Stream 通过分段处理数据,提升应用性能。

4.3.3 代码示例:

const fs = require('fs'); // 引入文件系统模块
const readStream = fs.createReadStream('input.txt'); // 创建读取流
const writeStream = fs.createWriteStream('output.txt'); // 创建写入流// 使用管道传递数据
readStream.pipe(writeStream);
console.log('文件流处理完成');

4.3.4 代码解释:

  1. createReadStream():逐步读取文件内容,避免一次性加载。
  2. createWriteStream():逐步写入文件,提高性能。
  3. .pipe():将读取流的数据传输到写入流。

4.4 Node.js 模块系统

4.4.1 用途及能做什么:

  • 组织代码为多个模块,提高代码的复用性和可维护性。
  • 支持引入第三方模块和自定义模块。

4.4.2 解决的问题:

  • 避免代码冗余,使大型应用更易于维护和扩展。

4.4.3 代码示例:

math.js:

exports.add = (a, b) => a + b;

app.js:

const math = require('./math'); // 引入自定义模块
console.log(`1 + 2 = ${math.add(1, 2)}`);

代码解释:

  1. exports:导出模块中的函数。
  2. require():引入模块,并使用模块中的函数。

4.5 Node.js 路由

4.5.1 用途及能做什么:

  • 定义 请求路径与响应逻辑,适用于 Web 应用和 API 服务。

4.5.2 解决的问题:

  • 管理不同页面或路径,使 Web 应用更易于维护和扩展。

4.5.3 代码示例:

const express = require('express'); // 引入 Express 框架
const app = express(); // 创建 Express 应用// 定义首页路由
app.get('/', (req, res) => res.send('欢迎访问首页'));// 定义关于页面路由
app.get('/about', (req, res) => res.send('关于我们'));app.listen(3000, () => console.log('服务器运行于 http://localhost:3000'));

4.5.4 代码解释:

  1. express():创建 Express 应用实例。
  2. app.get():定义 GET 请求路由。
  3. res.send():发送响应内容。

4.6 Node.js 全局对象

4.6.1 用途及能做什么:

  • 提供 常用的全局工具,如文件路径和计时器。

4.6.2 解决的问题:

  • 简化开发任务,无需重复引入常见工具模块。

4.6.3 代码示例:

console.log('当前文件:', __filename);
setTimeout(() => console.log('3秒后执行'), 3000);

4.6.3 代码解释:

  1. __filename:获取当前文件的绝对路径。
  2. setTimeout():延迟执行回调函数。

4.7 Node.js RESTful API

4.7.1 用途及能做什么:

  • 实现 客户端和服务器之间的数据交互

4.7.2 解决的问题:

  • 提供标准化的接口,支持前后端分离开发。

4.7.3 代码示例:

const express = require('express');
const app = express();
app.use(express.json());let users = [{ id: 1, name: 'Alice' }];app.get('/users', (req, res) => res.json(users));
app.post('/users', (req, res) => {const newUser = req.body;users.push(newUser);res.status(201).json(newUser);
});app.listen(3000, () => console.log('API 运行于 http://localhost:3000'));

4.7.4 代码解释:

  1. app.use():使用 JSON 解析中间件。
  2. app.get():定义 GET 请求路由,返回用户列表。
  3. app.post():定义 POST 请求路由,添加新用户。

4.8 Node.js 文件系统

4.8.1 用途及能做什么:

  • 处理 文件和目录的读写操作

4.8.2 解决的问题:

  • 实现应用与本地文件系统的交互。

4.8.3 代码示例:

const fs = require('fs');fs.writeFile('test.txt', 'Hello, Node.js!', (err) => {if (err) throw err;console.log('文件已写入');
});fs.readFile('test.txt', 'utf8', (err, data) => {if (err) throw err;console.log('文件内容:', data);
});

4.8.4 代码解释:

  1. fs.writeFile():异步写入文件。
  2. fs.readFile():异步读取文件内容。

4.9 Node.js GET/POST 请求

4.9.1 用途及能做什么:

  • 处理 HTTP 请求,支持客户端与服务器之间的数据交互。
  • GET 用于获取资源,POST 用于提交数据。

4.9.2 解决的问题:

  • 提供基础的 Web 服务功能,支持数据的获取和提交。

4.9.3 代码示例:

const http = require('http'); // 引入 HTTP 模块const server = http.createServer((req, res) => {if (req.method === 'GET') {res.end('GET 请求响应'); // 响应 GET 请求} else if (req.method === 'POST') {res.end('POST 请求响应'); // 响应 POST 请求}
});// 启动服务器并监听端口 3000
server.listen(3000, () => console.log('服务器运行于 http://localhost:3000'));

4.9.4 代码解释:

  1. http.createServer():创建 HTTP 服务器。
  2. req.method:检查请求的类型(GET 或 POST)。
  3. res.end():结束响应并发送数据给客户端。

4.10 Node.js 工具模块

4.10.1 用途及能做什么:

  • 提供 加密、调试和格式化字符串 等常用工具。
  • 适用于:开发安全性需求较高的应用,如用户身份验证和数据加密。

4.10.2 解决的问题:

  • 简化日常开发任务,提供现成的加密和调试工具。

4.10.3 代码示例:

const crypto = require('crypto'); // 引入加密模块const hash = crypto.createHash('sha256').update('Hello').digest('hex');
console.log('SHA256 哈希值:', hash);

4.10.4 代码解释:

  1. crypto.createHash():创建 SHA256 哈希对象。
  2. .update():向哈希对象添加数据。
  3. .digest():计算哈希值,并将其以十六进制格式输出。

4.11 Node.js Web 模块

4.11.1 用途及能做什么:

  • 快速创建 Web 服务器,处理 HTTP 请求。
  • 支持静态页面或动态内容的返回。

4.11.2 解决的问题:

  • 让开发者无需复杂配置就能快速启动 Web 服务。

4.11.3 代码示例:

const http = require('http'); // 引入 HTTP 模块http.createServer((req, res) => {res.writeHead(200, { 'Content-Type': 'text/html' }); // 设置响应头res.end('<h1>Hello, World!</h1>'); // 返回 HTML 内容
}).listen(3000);console.log('服务器运行于 http://localhost:3000');

4.11.4 代码解释:

  1. http.createServer():创建 HTTP 服务器。
  2. res.writeHead():设置响应头信息。
  3. res.end():返回响应内容,并结束请求。

4.12 Node.js Express 框架

4.12.1 用途及能做什么:

  • Express 是一个轻量级框架,用于构建 Web 应用和 API。
  • 支持路由管理和中间件的灵活使用。

4.12.2 解决的问题:

  • 简化了服务器开发流程,使路由管理更加方便。

4.12.3 代码示例:

const express = require('express'); // 引入 Express 框架
const app = express(); // 创建 Express 应用app.get('/', (req, res) => res.send('Hello Express!')); // 定义 GET 请求路由app.listen(3000, () => console.log('服务器运行于 http://localhost:3000'));

4.12.4 代码解释:

  1. express():创建 Express 应用实例。
  2. app.get():定义 GET 请求路由。
  3. res.send():发送响应内容。

4.13 Node.js 多进程

4.13.1 用途及能做什么:

  • 创建 多个进程 执行任务,提高并发性能。
  • 适用于 CPU 密集型任务异步操作

4.13.2 解决的问题:

  • 避免单线程阻塞,提高应用的响应速度。

4.13.3 代码示例:

const { exec } = require('child_process'); // 引入子进程模块exec('ls', (err, stdout, stderr) => {if (err) {console.error(`错误: ${stderr}`);return;}console.log(`输出: ${stdout}`);
});

4.13.4 代码解释:

  1. exec():执行系统命令,并返回结果。
  2. stdout:输出命令执行的结果。
  3. stderr:输出错误信息。

4.14 Node.js MySQL

4.14.1 用途及能做什么:

  • 连接和操作 MySQL 数据库,执行查询和数据管理。
  • 常用于 用户信息、订单管理和数据分析 系统。

4.14.2 解决的问题:

  • 实现结构化数据的存储和查询。

4.14.3 代码示例:

const mysql = require('mysql'); // 引入 MySQL 模块const connection = mysql.createConnection({host: 'localhost',user: 'root',password: '',database: 'test'
});connection.connect(); // 连接数据库// 执行查询操作
connection.query('SELECT * FROM users', (err, results) => {if (err) throw err;console.log('用户数据:', results);
});connection.end(); // 关闭连接

4.14.4 代码解释:

  1. mysql.createConnection():创建数据库连接。
  2. connection.query():执行 SQL 查询。
  3. connection.end():关闭数据库连接。

4.15 Node.js MongoDB

4.15.1 用途及能做什么:

  • 连接 MongoDB 数据库,处理 文档型数据
  • 适用于 灵活的数据模型,如用户信息、传感器数据等。

4.15.2 解决的问题:

  • 提供灵活的数据存储方式,适应不断变化的数据结构。

4.15.3 代码示例:

const { MongoClient } = require('mongodb'); // 引入 MongoDB 客户端
const url = 'mongodb://localhost:27017'; // MongoDB 连接地址
const client = new MongoClient(url); // 创建客户端实例async function run() {await client.connect(); // 连接到 MongoDBconst db = client.db('test'); // 选择数据库const users = await db.collection('users').find({}).toArray(); // 查询集合中的数据console.log('用户:', users); // 打印查询结果await client.close(); // 关闭连接
}run().catch(console.error); // 捕获错误

4.15.4 代码解释:

  1. MongoClient:创建用于连接 MongoDB 的客户端实例。
  2. client.connect():连接数据库。
  3. db.collection():选择数据库中的集合。
  4. find().toArray():查询数据并转换为数组。
  5. client.close():关闭数据库连接。

5.基于 Node.js 和 MySQL 的简易 CMS 系统开发

步骤 1:创建项目结构

simple-cms
├── models
│   └── article.js
├── routes
│   └── articles.js
├── views
│   ├── index.ejs
│   ├── articles
│   │   ├── new.ejs
│   │   ├── edit.ejs
│   │   └── show.ejs
├── config
│   └── database.js
├── app.js
└── package.json

步骤 2:安装依赖

执行以下命令初始化项目,并安装相关包:

npm install express mysql2 sequelize ejs body-parser

步骤 3:配置 MySQL 数据库连接

创建 config/database.js

const { Sequelize } = require('sequelize');// 配置数据库连接
const sequelize = new Sequelize('simple_cms', 'root', 'password', {host: 'localhost',dialect: 'mysql',
});module.exports = sequelize;

确保 MySQL 数据库中有一个名为 simple_cms 的数据库,并且 MySQL 服务已启动。

步骤 4:创建模型文件 models/article.js

const { DataTypes } = require('sequelize');
const sequelize = require('../config/database');// 定义 Article 模型
const Article = sequelize.define('Article', {title: {type: DataTypes.STRING,allowNull: false,},content: {type: DataTypes.TEXT,allowNull: false,},createdAt: {type: DataTypes.DATE,defaultValue: DataTypes.NOW,},
});module.exports = Article;

步骤 5:创建路由文件 routes/articles.js

const express = require('express');
const Article = require('../models/article');
const router = express.Router();// 获取所有文章
router.get('/', async (req, res) => {const articles = await Article.findAll({ order: [['createdAt', 'DESC']] });res.render('index', { articles });
});// 新建文章页面
router.get('/new', (req, res) => {res.render('articles/new', { article: {} });
});// 显示单篇文章
router.get('/:id', async (req, res) => {const article = await Article.findByPk(req.params.id);if (!article) return res.redirect('/');res.render('articles/show', { article });
});// 创建文章
router.post('/', async (req, res) => {const { title, content } = req.body;try {const article = await Article.create({ title, content });res.redirect(`/articles/${article.id}`);} catch (error) {res.render('articles/new', { article: { title, content } });}
});// 编辑文章页面
router.get('/edit/:id', async (req, res) => {const article = await Article.findByPk(req.params.id);res.render('articles/edit', { article });
});// 更新文章
router.post('/edit/:id', async (req, res) => {const { title, content } = req.body;try {await Article.update({ title, content }, { where: { id: req.params.id } });res.redirect(`/articles/${req.params.id}`);} catch (error) {res.redirect('/');}
});// 删除文章
router.post('/delete/:id', async (req, res) => {try {await Article.destroy({ where: { id: req.params.id } });res.redirect('/');} catch (error) {res.redirect('/');}
});module.exports = router;

步骤 6:创建主应用文件 app.js

const express = require('express');
const bodyParser = require('body-parser');
const articleRouter = require('./routes/articles');
const sequelize = require('./config/database');
const app = express();// 设置模板引擎
app.set('view engine', 'ejs');// 中间件
app.use(bodyParser.urlencoded({ extended: false }));
app.use('/articles', articleRouter);// 数据库同步
sequelize.sync().then(() => console.log('Database synced'));// 主页路由
app.get('/', (req, res) => {res.redirect('/articles');
});// 启动服务器
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {console.log(`Server is running on http://localhost:${PORT}`);
});

步骤 7:创建模板文件

views/index.ejs

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Simple CMS</title>
</head>
<body><h1>All Articles</h1><a href="/articles/new">Create New Article</a><ul><% articles.forEach(article => { %><li><a href="/articles/<%= article.id %>"><%= article.title %></a></li><% }) %></ul>
</body>
</html>

views/articles/new.ejs

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>New Article</title>
</head>
<body><h1>Create a New Article</h1><form action="/articles" method="POST"><input type="text" name="title" placeholder="Title" required /><textarea name="content" placeholder="Content" required></textarea><button type="submit">Create</button></form><a href="/">Back to Home</a>
</body>
</html>

views/articles/show.ejs

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title><%= article.title %></title>
</head>
<body><h1><%= article.title %></h1><p><%= article.content %></p><a href="/articles/edit/<%= article.id %>">Edit</a><form action="/articles/delete/<%= article.id %>" method="POST" style="display:inline;"><button type="submit">Delete</button></form><a href="/">Back to Home</a>
</body>
</html>

views/articles/edit.ejs

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Edit Article</title>
</head>
<body><h1>Edit Article</h1><form action="/articles/edit/<%= article.id %>" method="POST"><input type="text" name="title" value="<%= article.title %>" required /><textarea name="content" required><%= article.content %></textarea><button type="submit">Update</button></form><a href="/">Back to Home</a>
</body>
</html>

步骤 8:启动应用

确保 MySQL 数据库服务正常运行,然后执行以下命令:

node app.js

访问:http://localhost:3000

步骤9:查看

所有文章

创建文章

查看文章

更新文章

查看文章

数据库查看

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Golang | Leetcode Golang题解之第475题供暖器

题目&#xff1a; 题解&#xff1a; func findRadius(houses, heaters []int) (ans int) {sort.Ints(houses)sort.Ints(heaters)j : 0for _, house : range houses {dis : abs(house - heaters[j])for j1 < len(heaters) && abs(house-heaters[j]) > abs(house-…

【vue+printJs】前端打印, 自定义字体大小, 自定义样式, 封装共享样式

效果示例 思维导图 目录 1,基本使用1, 依赖下载2, 页面导入3, 修改字体大小(可行但不推荐) 2, 自定义样式,字体大小1, 修改字体大小(推荐)2, 自定义样式3, 封装共享样式 3, 去除页面页脚内容4, 测试案例demo, 直接cv可用5, print-js的其他参数说明 1,基本使用 1, 依赖下载 …

Java 小游戏《超级马里奥》

文章目录 一、效果展示二、代码编写1. 素材准备2. 创建窗口类3. 创建常量类4. 创建动作类5. 创建关卡类6. 创建障碍物类7. 创建马里奥类8. 编写程序入口 一、效果展示 二、代码编写 1. 素材准备 首先创建一个基本的 java 项目&#xff0c;并将本游戏需要用到的图片素材 image…

小马识途海外媒体推广有何优势?

互联网让地球变得像一个村子一样&#xff0c;信息可以瞬间变得人尽皆知&#xff0c;商品和服务也同样习惯了跨国合作。中国不少物美价廉的产品在世界各地都很受欢迎&#xff0c;国内小资群体对国外的服饰和美妆更是偏爱有加。小马识途营销顾问认为&#xff0c;中国品牌不出走国…

“趋势买点”,智能捕捉市场底部的工具指标

“趋势买点”&#xff0c;智能捕捉市场底部的工具指标 分享的这个指标包含副图与主图&#xff0c;不含未来函数&#xff0c;旨在通过分析市场波动找到可靠的买点信号&#xff0c;以便在底部进行抄底操作。 "趋势买点"的副图信号作为判断市场底部的重要依据&#xff0…

只想简单跑个 AI 大模型,却发现并不简单

之前我用 Ollama 在本地跑大语言模型&#xff08;可以参考《AI LLM 利器 Ollama 架构和对话处理流程解析》&#xff09;。这次想再捣鼓点进阶操作&#xff0c;比如 fine-tuning。 我的想法是&#xff1a;既然有现成的大模型&#xff0c;为什么不自己整理些特定领域的数据集&am…

6云图书管理系统-图书展示

1 /src/store中新增userInfo.js&#xff0c;用于保存用户的登录信息 import { defineStore } from "pinia" import { ref } from vueexport const userInfoStore defineStore(userInfo, () > {//1.定义用户信息const info ref({})const isAdmin ref(false)//2…

css 仿微信朋友圈图片自适应九宫格

不好用请移至评论区揍我 原创代码,请勿转载,谢谢! 示例效果 1 ~ 5张图与5 ~ 9张图 代码实现 <view style="

卸载Python

1、查看安装框架位置并删除 Sudo rm -rf /Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8 2、查看应用并删除 在 /Applications/Python 3.x 看是否存在&#xff0c;如果存在并删除。 3、删除软连接 ls -l /usr/bin/py* 或 ls -…

什么是分布式锁?Redis的分布式锁又是什么?

什么是分布式锁&#xff1f; 分布式锁是一种用于解决分布式系统中多节点对共享资源并发访问问题的机制。在分布式系统中&#xff0c;多个服务器实例或服务进程可能同时操作某个共享资源&#xff08;如数据库记录、缓存条目、文件等&#xff09;&#xff0c;导致数据不一致或竞…

千鹿 AI:强大的抠图神器,让你的工作效率飙升99%

宝子们&#xff0c;今天一定要给大家分享一款超厉害的抠图工具 —— 千鹿 AI。千鹿 AI 用起来真的是极其方便&#xff0c;仅仅上传一张图片&#xff0c;短短几秒钟的时间&#xff0c;就能够获得一张边缘超级清晰的抠图成品&#xff0c;实在是令人惊叹。 鹿 AI 的厉害之处有很多…

【Linux系统编程】环境基础开发工具使用

目录 1、Linux软件包管理器yum 1.1 什么是软件包 1.2 安装软件 1.3 查看软件包 1.4 卸载软件 2、Linux编辑器-vim 2.1 vim的概念 2.2 vim的基本操作 2.3 vim的配置 3、Linux编译器-gcc/g 3.1 gcc编译的过程​编辑​编辑​编辑 3.2 详解链接 动态链接 静态链接 4…

二百六十九、Kettle——ClickHouse清洗ODS层原始数据增量导入到DWD层表中

一、目的 清洗ClickHouse的ODS层原始数据&#xff0c;增量导入到DWD层表中 二、实施步骤 2.1 newtime select( select create_time from hurys_jw.dwd_statistics order by create_time desc limit 1) as create_time 2.2 替换NULL值 2.3 clickhouse输入 2.4 字段选择 2.5 …

UDP反射放大攻击防范手册

UDP反射放大攻击是一种极具破坏力的恶意攻击手段。 一、UDP反射放大攻击的原理 UDP反射放大攻击主要利用了UDP协议的特性。攻击者会向互联网上大量的开放UDP服务的服务器发送伪造的请求数据包。这些请求数据包的源IP地址被篡改为目标受害者的IP地址。当服务器收到这些请求后&…

『网络游戏』服务器启动逻辑【16】

新建Visual Studio工程命名为NetGameServer 重命名为ServerStart.cs 创建脚本&#xff1a; 编写脚本&#xff1a;ServerRoot.cs 编写脚本&#xff1a;ServerStart.cs 新建文件夹 调整脚本位置 新建文件夹 新建文件夹网络服务 创建脚本&#xff1a;NetSvc.cs 编写脚本&#xff1…

【word】文章里的表格边框是双杠

日常小伙伴们遇到word里插入的表格&#xff0c;边框是双杠的&#xff0c;直接在边框和底纹里修改边框的样式就可以&#xff0c;但我今天遇到的这个有点特殊&#xff0c;先看看表格在word里的样式是怎么样&#xff0c;然后我们聊聊如何解决。 这个双杠不是边框和底纹的设置原因…

linux线程 | 一点通你的互斥锁 | 同步与互斥

前言&#xff1a;本篇文章主要讲述linux线程的互斥的知识。 讲解流程为先讲解锁的工作原理&#xff0c; 再自己封装一下锁并且使用一下。 做完这些就要输出一堆理论性的东西&#xff0c; 但博主会总结两条结论&#xff01;&#xff01;最后就是讲一下死锁。 那么&#xff0c; 废…

《量子之歌》

第一章&#xff1a;曙光 在2045年的未来&#xff0c;人工智能不再是科幻作品中的虚构&#xff0c;而是成为了日常生活的一部分。在这个时代&#xff0c;深度学习模型已经变得如此庞大和复杂&#xff0c;以至于即使是最快的超级计算机也需要数小时才能完成一次完整的训练。 陈欣…

大华智能云网关注册管理平台 SQL注入漏洞复现(CNVD-2024-38747)

0x01 产品简介 大华智能云网关注册管理平台是一款专为解决社会面视频资源接入问题而设计的高效、便捷的管理工具,平台凭借其高效接入、灵活部署、安全保障、兼容性和便捷管理等特点,成为了解决社会面视频资源接入问题的优选方案。该平台不仅提高了联网效率,降低了联网成本,…

【前端】制作一个自己的网页(4)

刚才我们完成了网页中标题与段落元素的学习。在实际开发时&#xff0c;一个网页通常会包含多个相同元素&#xff0c;比如多个标题与段落。 对于相同标签的元素&#xff0c;我们又该如何区分定位呢&#xff1f; 对多个相同的标签分类 比如右图设置了七个段落元素&#xff0c;它…