Node.js博客项目开发思路笔记

news2025/1/15 21:51:52

博客项目介绍

1. 目标

  • 开发一个博客系统,具备博客基本功能
  • 只开发 server 端,不关心前端

2. 需求

  • 首页、作者页、博客详情页
  • 登陆页
  • 管理中心、新建页、编辑页

3. 技术方案

数据如何存储

  • 博客
idtitlecontentcreatetimeauthor
1标题 1内容 11111112zhangsan
2标题 2内容 21111111lisi
  • 用户
idusernamepasswordrealname
1zhangsan123张三
2lisi.123李四

如何与前端对接接口,即接口设计

描述接口方法url参数备注
获取博客列表/api/blog/listgetauthor 作者,keyword搜索关键字参数为空,则不进行查询过滤
获取一篇博客的详情/api/blog/detailgetid
新增一篇博客/api/blog/newpostpost中有新增的信息
更新一遍博客/api/blog/updatepostidpostData中包含更新内容
删除一篇博客/api/blog/delpostid
登陆/api/user/loginpostpostData包含用户名和密码

4. 开发接口(原生node,不使用框架)

4.1 http请求过程

  1. DNS解析,建立TCP连接(三握四挥),发起请求;
  2. serve 端接收请求处理数据,响应返回数据;
  3. 客户端接收到数据,渲染页面,执行脚本。

4.2 搭建开发环境

  1. 使用 nodemon 检测文件变化,自动重启node项目;
  2. 使用 cross-env 设置环境变量。

4.3 路由和数据

  1. 初始化路由:根据之前的技术方案的设计,做出路由;
  2. 返回假数据:将路由和数据分离,符和设计原则。

4.4 项目结构

根目录下

  • bin/www.js 处理端口和 有关 http 服务的相关事宜
  • app.js 处理基本逻辑(导入路由函数,传递req,res参数),和 404 页面
  • router 文件夹,完成路由规则(分为 blog.js、 user.js ),只处理路由不关心数据的处理
  • controller/blog.js 文件, 连接数据库,处理数据,在 router/blog.js 中使用,类似工具
  • model/resModel 文件, 完成响应数据模块 resModel,封装成功和失败类,在 router/blog.js 的某个路径成功获取数据后就使用成功类响应数据和消息提示。

4.5 处理 post

使用 promise 优化 post 请求的数据,放入 req.body 里。对于请求方法不正确或者请求头不匹配直接 resolve 一个空对象,并不需要当作一个错误。应为读取 data 的过程是异步的,所以需要将原来的命中路由的逻辑放在promise中,在 app.js 中实现。

部分代码如下:

/**
 * 处理 post data
 */
const getPostData = (req) => {
  const promise = new Promise((resolve, reject) => {
    // 方法不是 post
    ...
    // 请求头格式不是 json
    ...
    let postData = "";
    req.on("data", (chunk) => {
      // 将json格式的参数转为字符串保存
      postData += chunk.toString();
    });

    req.on("end", () => {
      // null
      if (!postData) {
        resolve({});
        return;
      }
      // success
      resolve(JSON.parse(postData));
    });
  });
  return promise;
};
// 处理 post data
  getPostData(req).then((postData) => {
    // 将数据放入body
    req.body = postData;
    /**
     *  blog 路由
     */
    const blogData = handleBlogRouter(req, res);
    // 命中 blog 路由
    ...
    /**
     *  user 路由
     */
    const userData = handleUserRouter(req, res);
    // 命中 user 路由
    ...    
	// 处理 404
    ...
  });

5.数据存储

5.1.实现思路

  • 建立数据库myblog,建立博客表、和用户表
  • conf/db.js 下封装数据库工具,处理开发和生产环境下的数据库连接配置
  • db/mysql.js使用promise获取数据库的数据,resolvegetList工具,在getList中只需处理 sql语句,然后在app.js 中使用.then,发送 res.end 给客户端

6.登陆功能

核心:登陆鉴权和信息存储

  • cookie和session

  • session 写入 redis

  • 开发登陆功能-和前端联调 Nginx 反向代理

session/cookie

前端保存 cookie 携带 userId,后端通过是否有 userId 进行一系列操作,当登陆成功但是没有 session 时需要设置 session

目前有关session的问题

  • session 是直接储存 js 变量,放在 node.js 进程内存中;
  • 第一,进程内存有限,访问量过大时内存爆增,可能导致服务崩溃;
  • 第二,正式线上运行时多进程,进程之间无法共享内存。

解决:使用 redis

为什么:

  • session 访问非常频繁,不能使用 mysql,对性能要求高。
  • 并且 session 可以丢失,无须内存永久保存。
  • session数据量不大,没必要使用 mysql

要使用 Redis,在 Node.js 中存储会话(session),你需要执行以下步骤:

1. 下载和安装 Redis:

官方网站(https://redis.io/download)

启动服务:执行 redis-server,建立连接和操作:执行:redis-cli

基本使用语法

  • 添加:set [key] [value]
  • 获取:get [key]
  • 删除:del [key]
  • 获取所有key: keys *

2. 配置 Redis:

安装完成后,你需要配置 Redis 服务器。打开 Redis 配置文件(redis.conf)并进行必要的更改。确保 bind 配置项设置为允许远程连接(如果需要从 Node.js 应用程序访问 Redis)。

3. 在 Node.js 中安装 Redis 客户端:

npm install redis

这将安装 Redis 客户端库,使你能够在 Node.js 应用程序中与 Redis 进行交互。

4. 在 Node.js 应用程序中存储会话:

首先,你需要在 Node.js 应用程序中创建与 Redis 的连接。使用 Redis 客户端库提供的方法进行连接。

const redis = require('redis');
const client = redis.createClient(); // 创建与 Redis 的连接

client.on('error', (err) => {
  console.error('Redis连接错误:', err);
});

// 储存会话示例
app.post('/login', (req, res) => {
  // 处理用户登录逻辑
  // ...

  // 在 Redis 中存储会话
  client.set(req.sessionID, JSON.stringify(req.user), (err, reply) => {
    if (err) {
      console.error('存储会话错误:', err);
      return res.status(500).send('存储会话失败');
    }
    console.log('会话已存储:', reply);
    res.send('登录成功');
  });
});

在上面的示例中,我们使用 Redis 客户端的 set 方法将会话数据以 JSON 字符串的形式存储在 Redis 中。req.sessionID 是会话的唯一标识符,通常存储在用户的浏览器 cookie 中。req.user 是用户对象,我们将其转换为 JSON 字符串后存储在 Redis 中。

和前端联调

  • 登陆依赖 cookie 必须使用 浏览器联调
  • cookie 跨域不共享,前端和 server 端必须同域
  • 需要使用 nginx 代理,使前后端同域

登陆总结:

Cookie和Session都是用于跟踪用户状态的技术。它们之间有一些区别:

  1. Cookie:Cookie是一种存储在客户端的小型文本文件,用于保存用户的一些信息。当用户访问一个网站时,服务器会将Cookie发送到用户的浏

  2. 用户在登录页面输入用户名和密码。

  3. 客户端将用户名和密码发送到服务器。

  4. 服务器验证用户名和密码。如果验证成功,服务器会创建一个Session,并将Session ID发送给客户端(通常通过Cookie)。

  5. 客户端保存Session ID,并在后续请求中将其发送回服务器。

  6. 服务器根据Session ID识别用户,并获取其会话信息。

在使用Redis存储Session信息时,可以将Session ID作为键,将用户会话信息作为值。这样,当服务器需要获取用户会话信息时,可以直接从Redis中查询,而不需要访问数据库,从而提高性能。同时,由于Redis支持分布式存储,可以方便地扩展Session存储容量。

7.日志

  1. 访问日志 access log (最重要);
  2. 自定义日志,包括自定义事件、错误记录。

大致思路:

  • 封装 utils log.js 工具
  • 使用 writerStream 分别实现 access 访问日志,和错误、事件日志
  • 分别导出使用
/**
 * 写日志的一小步操作
 * @param {Function} writeStream
 * @param {string} log
 */
const writeLog = function (writeStream, log) {
  writeStream.write(log + "\n");
};

/**
 * 写入流函数
 * @param {string} fileName -logs 文件夹下的文件名,你将要写入的文件
 * @return writeStream
 */
const createWriteStream = function (fileName) {
  const fullFilePath = path.join(__dirname, "../", "../", "logs", fileName);
  const writeStream = fs.createWriteStream(fullFilePath, { flags: "a" });
  return writeStream;
};

// 1. 写入访问日志
// 利用 createWriteStream 函数创建 access 写入流
const accessWriteStream = createWriteStream("access.log");
const access = function (log) {
  writeLog(accessWriteStream, log);
};

// 2. 写入错误日志
...
// 3. 写入事件日志
...
module.exports = {
  ...
};

日志拆分

使用 linux 的 crontab 命令,即定时任务。

使用 crontab -e 写入在什么时候执行什么文件

* 0 * * * sh /Users/jiangchuanyou/Desktop/项目/node博客项目/src/utils/copy.sh

以上就是在每天凌晨0点执行以下脚本

#!/bin/sh
cd /Users/jiangchuanyou/Desktop/项目/node博客项目/logs
cp access.log $(date +%Y-%m-%d).access.log
echo '' > access.log

8. 安全

  • sql 注入:窃取数据库内容;

解决方案:mysql 自带 escape 函数

  • xss 攻击:窃取前端 cookie 内容;

解决方案:转换特殊字符,使用 xss 函数,下载 npm 包 xss -s,直接使用 xss 函数包裹变量,以免生成危险的 js 代码

前端预防 xss 攻击

  1. 输入验证和过滤:对于用户输入的数据,进行输入验证和过滤,确保只接受预期的数据类型和格式。可以使用正则表达式、白名单过滤或使用专门的输入验证库来检查和清理用户输入。

  2. HTML转义:将用户输入的数据进行适当的 HTML 转义,确保任何特殊字符都被转义为它们的等效实体表示形式。这样可以防止恶意脚本在页面中执行。可以使用专门的转义函数或库,如htmlspecialchars等。

  3. 跨站点脚本保护:禁止内联 JavaScript 代码、限制只接受特定的 HTML 标签和属性。使用安全的 HTML 渲染库或模板引擎,这些库会自动转义用户输入。

  4. HTTP-only Cookie:将敏感信息存储在 HTTP-only Cookie 中,确保 JavaScript 无法访问该信息。这样可以减少 XSS 攻击者窃取会话信息的可能性。

  5. 内容安全策略(Content Security Policy,CSP):使用 CSP 可以限制页面中可以执行的脚本和资源。通过配置 CSP,可以指定允许的域、资源类型和加载方式,以减少 XSS 攻击的风险。

  6. 防止拼接 HTML 字符串:避免直接拼接用户输入的数据来构建 HTML 字符串。而是使用 DOM 操作或模板引擎来动态生成 HTML,确保数据被正确地转义和处理。

  7. 安全编码实践:遵循安全的编码实践,避免在代码中出现漏洞,如不信任的数据源、不安全的 eval() 使用、动态执行用户输入的代码等。

  • 密码加密:保障用户信息安全

9. 总结

流程图

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue购物车实例练习

功能介绍 金额 单价 * 数量金额会自动根据数量的变化进行变化,我们可以点击按钮增加或减少商品的数量。合计金额:只有在序号列号勾选上才会被计入总金额中,金额总数会根据用户的操作自动更新数据。删除:如图我们勾选了第2个商品&…

【开源项目】Easy-Trans数据翻译服务的快速入门及原理解析

项目介绍 easy-trans是一款用于做数据翻译的代码辅助插件&#xff0c;利用mybatis plus/jpa/beetsql 等ORM框架的能力自动查表&#xff0c;让开发者可以快速的把id/字典码 翻译为前端需要展示的数据。 快速入门 maven依赖 <properties> <fhs.release.version>2.…

痞子衡嵌入式:MCUBootUtility v5.0发布,初步支持i.MXRT1180

--   痞子衡维护的NXP-MCUBootUtility工具距离上一个大版本(v4.0.0)发布过去4个多月了&#xff0c;期间痞子衡也做过两个小版本更新&#xff0c;但不足以单独介绍。这一次痞子衡为大家带来了全新大版本v5.0.0&#xff0c;这次更新主要是想和大家特别聊聊恩智浦新一代 i.MXRT …

一个传统剧团的自救

今天我和大家分享一个 最近我在网上看到的案例。 是这样说的 在岭南地区 有一个较为偏远的地方 当地有一个传统的戏团 他们依托当地传统习俗 把戏曲一代一代流传下来 但是到了现在。 戏团面临传承中断 戏团解散的困境。 当地文化宣传员小林 知道这个情况后。 立马展开调查 并且…

Linux——gcc/g++编译器

gcc是用来编译C语言代码的编译器&#xff0c;而g是用来编译C代码的编译器的。 而gcc和g都是软件&#xff0c;需要使用yum进行下载 注&#xff1a;需要使用root权限才能下载 在C语言编译的过程中&#xff0c;会有四个过程: 1预处理&#xff0c;2编译&#xff0c;3汇编&#xf…

CB06551 PRD-B040SSIB-63

​ CB06551 PRD-B040SSIB-63 步进电机驱动器有什么参数   步进电机驱动器基本参数如下&#xff1a; a、供电电源&#xff0c;可据所驱动步进电机的电源规格进行选择。交流电源供电的&#xff0c;如AC80V&#xff0c;可用220V市电经降压变压器&#xff0c;提供给驱动器。选用变…

YOLO-NAS 如何将 YOLO-v8 甩在身后?

在使用目标检测模型方面&#xff0c;我已经积累了一些经验。所以当我听说这个火热的新玩意儿叫做 YOLO-NAS 时&#xff0c;我知道我必须去尝试一下。让我告诉你&#xff0c;这个家伙真是让人惊叹。它就像是目标检测模型中的埃隆马斯克——大胆、创新&#xff0c;稍微有点让人害…

关于我被敲诈勒索骗了 1w 多这件事

大家好&#xff0c;我是程序员贺同学。 昨晚遭遇了人生中第一次诈骗&#xff0c;损失金额 1w多&#xff0c;趁这两天情绪缓了缓&#xff0c;把过程记录了下来&#xff0c;希望对看到的人有所帮助。 昨晚报完警回来快 23 点&#xff0c;把手机上的重要图片&#xff0c;视频&…

嵌入式 QT多界面切换

目录 1. 添加界面类实现 1.1 添加第二个界面的类 1.2 添加第2个界面的头文件和槽函数 2. 工程管理实现 在Qt中&#xff0c;多界面切换是指在一个应用程序中使用多个不同的界面&#xff0c;并在它们之间进行切换。这种切换可以是用户触发的&#xff0c;例如点击按钮或选择菜…

建议收藏,最全ChatGPT 中文调教指南:提供各个领域的角色提示词(prompts)及使用技巧,当然也有不正经指南

ChatGPT是一种基于GPT&#xff08;Generative Pre-trained Transformer&#xff09;模型的聊天机器人&#xff0c;能够回答用户提出的问题和进行对话。它是由OpenAI开发的人工智能产品&#xff0c;具有自然语言处理和深度学习技术。 ChatGPT在日常的对话中&#xff0c;表现的非…

深度剖析JVM调优法则,神器Arthas从CPU/内存出发轻松掌握调优实战技巧

场景一、CPU过高 CPU占用过高排查思路&#xff1a; step1&#xff1a;进行arthas java -jar arthas-boot.jar step2&#xff1a;输入deashboard 如何不记得命令可以在控制台输入help step3&#xff1a;查看线程栈信息 thread ID 从线程栈信息中定位到具体的java代码。 场…

Ubuntu关机、重启和注销命令

学习linux系统&#xff0c;最重要的是使用各种命令对系统进行操作&#xff0c;打开各种软件&#xff0c;本次主要分析ubuntu中的关机&#xff0c;重启&#xff0c;注销命令的使用详解。 关机命令 shutdown 1)使用shutdown --help可以查看shutdown命令如何使用&#xff0c;当然也…

mssql计划

介绍 MSSQL计划是一个用于Microsoft SQL Server数据库管理的工具。它包含了一系列的功能&#xff0c;可以帮助管理员进行数据库的备份、恢复、优化、监控等操作&#xff0c;提高数据库的性能和可靠性。 MSSQL计划的主要功能包括&#xff1a; 备份和恢复数据库&#xff1a;可以…

【运维知识进阶篇】集群架构-HTTPS证书详解

HTTPS证书在企业中非常重要&#xff0c;因为HTTP不安全&#xff0c;采用HTTP协议容易受到劫持和篡改&#xff0c;如果是采用HTTPS&#xff0c;数据在传输过程中加密&#xff0c;可以避免报文信息被窃取篡改&#xff0c;避免网站传输时信息泄露。实现https&#xff0c;要了解SSL…

记录--九个超级好用的 Javascript 技巧

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 前言 在实际的开发工作过程中&#xff0c;积累了一些常见又超级好用的 Javascript 技巧和代码片段&#xff0c;包括整理的其他大神的 JS 使用技巧&#xff0c;今天筛选了 9 个&#xff0c;以供大家参考…

从选型工具到内核优化,从替代方法到迁移改造,河北移动联合云和恩墨以创新树标杆,推进国产数据库应用落地...

势在必行&#xff0c;电信行业国产化改造适逢其时 自十四五规划以来&#xff0c;伴随着“科技创新”和“信息安全”等相关政策的密集出台&#xff0c;我国信创产业正式进入高速发展期&#xff0c;力求通过构建各行业全栈国产IT体系&#xff0c;实现科技技术自主可控&#xff0c…

原来我真的不懂Spring

(1)Spring的生命周期:简单概括为4个阶段: 1.1 创建对象 1.2 DI属性赋值 1.3 初始化 1.4 销毁 (2) Bean的作用域 : 1. Singleton: 单例 2. Prototype: 多例 3. Request: 每次http请求都会创建一个新的bean 4. Session: ~ 5. ApplicationContext: ~ (3) 注册Bean的4种方式…

企业即时通讯如何让企业沟通变得简单

企业即时通讯&#xff0c;企业之间的沟通协作&#xff0c;最核心的价值在于能够将复杂的工作任务简化为更高效、更易于沟通的协作方式。如果员工之间没有协作&#xff0c;就没有办法进行高效的沟通&#xff0c;就会出现组织低效、沟通效率低等问题。那么如何将复杂的工作任务简…

多路复用是怎么回事?

《计算机组成原理》讲述的是如何去理解程序和计算。《操作系统》讲述的是如何去理解和架构应用程序。《计算机网络》讲述的是如何去理解今天的互联网。 现在来看&#xff0c;“计算机网络”也许是一个过时的词汇&#xff0c;它讲的是怎么用计算实现通信。今天我们已经发展到了一…

HTTPS(面试高频必须掌握)

目录 一、HTTPS背景 二、HTTPS 的工作过程 1. 对称加密 2.非对称加密 3. HTTPS 基本工作过程 3.1 使用对称密钥 3.2 引入非对称密钥&#xff08;面试高频问题&#xff09; 3.3 黑客的手段 3.4 引入证书 3.5 捋一捋 3.6 SSL/TLS 三、HTTP 与 HTTPS 区别&#xff08;…