本博客基于掘金小册子《Node + React 实战:从 0 到 1 实现记账本》的内容进行整合与编写,旨在构建一个系统的知识网络。

技术栈

  • eggjs
  • react
  • Mysql
  • DBever

必备工具

egg项目创建

1
2
3
$ mkdir egg-example && cd egg-example
$ cnpm init egg --type=simple
$ cnpm i

项目所需配置

post方法

[安全威胁 csrf 的防范」即网络请求的安防策略,你 Egg 启动的是本地地址http://127.0.0.1:7001 ,但是你请求的 POSTGET 接口是非本地计算机(别人的电脑),或者使用 Postman 发起请求,都会触发安防策略。

前往 config/config.default.js 做好白名单配置,这里我直接全部允许请求:

1
2
3
4
5
6
7
config.security = {
csrf: {
enable: false,
ignoreJSON: true
},
domainWhiteList: [ '*' ], // 配置白名单
};

Eggjs使用前端模板egg-view-ejs

我们开发一些简单的网页,想快速部署到云服务器上,就可以使用前端模板的开发形式。下面介绍该种方式如何操作:

首先安装插件 egg-view-ejs

1
npm install egg-view-ejs -save

然后在 config/plugin.js 里面声明需要用到的插件:

1
2
3
4
5
6
module.exports = {
ejs: {
enable: true,
package: 'egg-view-ejs'
}
};

紧接着我们需要去 config/config.default.js 里配置 ejs ,这一步我们会将 .ejs 的后缀改成 .html 的后缀。

1
2
3
config.view = {
mapping: {'.html': 'ejs'} //左边写成.html后缀,会自动渲染.html文件
};

上述的配置,指的是将 view 文件夹下的 .html 后缀的文件,识别为 .ejs

接着,在 app 目录下创建 view 文件夹,并且新建一个 index.html 文件,作为前端模板,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title><%-title%></title>
</head>
<body>
<!-- 使用模板数据 -->
<h1><%-title%></h1>
</body>
</html>

我们会在 Controller 内把变量注入到 index.html 文件,模板通过 <%-xx%>关键字获取到传入的变量。

下面修改 controller/home.js 下的 index 方法如下:

1
2
3
4
5
6
7
async index() {
const { ctx } = this;
// ctx.render 默认会去 view 文件夹寻找 index.html,这是 Egg 约定好的。
await ctx.render('index.html', {
title: '我是尼克陈', // 将 title 传入 index.html
});
}

我们尝试在浏览器打开 http://localhost:7001/,如下所示:

img

上述代码在服务端就已经构建完毕,输出的是一个纯静态的 HTML 文件,我们可以在浏览器右键点击「显示网页源代码」,查看网页源代码,如下所示:

img

正常情况下,在渲染的网页上看到的内容,如果在上述源代码页面内都能找到响应的部分,那可以理解为是服务端直接输出的 HTML 渲染的。

mysql信息配置

config.default.js 的数据库配置项中的数据库名称修改一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
exports.mysql = {
// 单数据库信息配置
client: {
// host
host: 'localhost',
// 端口号
port: '3306',
// 用户名
user: 'root',
// 密码
password: '你的数据库初始化密码', // Window 用户如果没有密码,可不填写
// 数据库名
database: 'juejue-cost',
},
// 是否加载到 app 上,默认开启
app: true,
// 是否加载到 agent 上,默认关闭
agent: false,
};

鉴权egg-jwt

我们需要在项目下安装 egg-jwt 插件,执行如下指令:

1
cnpm i egg-jwt --S

这是它的仓库地址,仓库内有一些简易的文档,具体的操作其实很多都没有写在文档里,我也是搜了很多相关的资料,才设计出这样一套鉴权流程。

config/plugin.js 下添加插件:

1
2
3
4
5
6
...
jwt: {
enable: true,
package: 'egg-jwt'
}
...

紧接着前往 config/config.default.js 下添加自定义加密字符串:

1
2
3
config.jwt = {
secret: 'Nick',
};

momentmkdirp 时间戳和新建文件夹

1
npm i moment mkdirp --S

egg 提供两种文件接收模式,1 是 file 直接读取,2 是 stream 流的方式。我们采用比较熟悉的 file 形式。所以需要前往 config/config.default.js 配置好接收形式:

1
2
3
config.multipart = {
mode: 'file'
};

multipart 配置项有很多选项,比如 whitelist 上传格式的定制,fileSize 文件大小的限制,这些都可以在文档中查找到。

this.config.uploadDir 需要全局声明,便于后续通用,在 config/config.default.js 中声明如下:

1
2
3
4
5
// add your user config here
const userConfig = {
// myAppName: 'egg',
uploadDir: 'app/public/upload'
};

解决跨域egg-cors

首先安装 egg-cors 插件 npm i egg-cors,安装好之后,前往 config/plugins.js 下添加属性:

1
2
3
4
cors: {
enable: true,
package: 'egg-cors',
},

然后在 config.default.js 配置如下:

1
2
3
4
5
config.cors = {
origin: '*', // 允许所有跨域访问
credentials: true, // 允许 Cookie 跨域跨域
allowMethods: 'GET,HEAD,PUT,POST,DELETE,PATCH'
};

Mysql下载

MySQL :: Download MySQL Community Server

image-20250315215858717

下载

选择8.0.41的版本,一定不要最新版

点击「Download」之后,会让你注册登录账号,此时可以选择点击下面这段文字,跳过注册登录。

img

解压

到你想要放置的文件夹中解压

且在 mysql-8.0.24-winx64 文件夹内新建一个空的 my.ini

配置系统变量

点击右下角的「环境变量(N)」按钮,在系统变量里新建名为 「MYSQL_HOME」,变量值就是你上一步解压后存放 MySQL 文件的安装路径。我的安装路径如下所示:

img

设置 Path,在 Path 里面新增 bin 目录。双击 Path,然后点击新建按钮,添加 %MYSQL_HOME%\bin 如下:

img

安装

首先,以管理员身份运行 cmdWindows 10 下,直接右键「开始」,找到「命令提示符(管理员)(A)」,点击打开 cmd

1、进入安装 mysql 的目录,进入 bin:

img

2、运行安装指令:

1
mysqld --install

安装成功的话,控制台会提示如下:

img

3、运行如下指令生成 data 目录:

1
mysqld --initialize-insecure --user=mysql

4、启动 mysql 服务:

1
net start mysql

img

此时,不用怀疑,你已经成功在你的本地启动了 MySQL 服务。

5、(关键步骤)

如果后续用 egg-mysql 插件连接数据库的时候会报下面这样的错误:

img

这是因为 8.0 之前的 mysql 版本,加密规则是 mysql_native_password,而在 8.0 之后,加密规则变为 caching_sha2_password。此时你如果用的是 8.0 以前的版本,那么通过 egg 启动项目连接数据库是没问题的,我们这里使用的是 8.0 以后的版本,所以就会出现上述错误。

解决办法:

以管理员身份运行 cmd,上文已经提到过。通过 mysql -u root -p 回车进入 mysql 如下所示:

img

我已经设置过密码了,所以上图我是用密码登录的,你若是没有设置,可以直接敲回车登录。

输入下面指令:

1
2
3
use mysql;
alter user 'root'@'localhost' identified with mysql_native_password by '你的密码';
flush privileges;

上述指令的作用是,还原 MySQL 的加密规则,还原之后,你再 egg 项目中连接 MySQL 的时候,就不会报错了。

并且上述指令中的 「你的密码」,如果你设置的话,那就会生效,成为以后你登录数据库的密码。

注意,指令一定要按照上述输入,包括最后的分号,不然会指令错误。