https://eggjs.org/zh-cn/basics/structure.html

介绍

image.png
image.png image.png

image.png

基础

image.png

各功能间的关系

image.png
image.png

MVC

image.png

====================

安装、启动

image.png

基础功能

路由 router.js

路由跳转,就是用户输入特定的路径,就调用对应的控制器进行操作
image.png
image.png

动态路由

image.png
image.png
app/controller/home.js 控制器里面,通过ctx.params的方式获得
image.png
image.png

控制器跳转

image.png

控制器 Controller

控制器:处理业务逻辑
image.png
image.png
admin.js(新增的控制器的js文件)

  1. 'use strict';
  2. const Controller = require('egg').Controller;
  3. class AdminController extends Controller {
  4. async index() {
  5. const { ctx } = this;
  6. ctx.body = 'hi, admin';
  7. }
  8. }
  9. module.exports = AdminController;

一个控制器可以调用多个服务,但是控制器不能调用控制器,服务不能调用控制器
image.png

中间件

在匹配路由之前进行的一些操作,比如鉴权、配置全局变量等。不管用户怎么请求,请求到哪个地址,都会先通过中间件。
https://eggjs.org/zh-cn/basics/middleware.html
image.png image.png
image.png

定义中间件
image.png

启用中间件
image.png

中间件传值,可以通过在config.default.js里面配置好值,然后直接就给中间件的option获得
image.png
image.png
例子:屏蔽一些ip访问
image.png

服务 Service

和数据打交道,主要是请求数据、操作数据等复杂操作

创建一个服务
image.png

在控制器里面调用服务(异步)

  1. let xxx = await this.ctx.service.服务所在的文件名.服务的方法();

image.png
服务都是集成egg.Service,因此可以调用下面this.xxx,甚至服务之间都可以调用服务。
image.png
一个控制器可以调用多个服务,但是控制器不能调用控制器,服务不能调用控制器
image.png

扩展 extend

https://eggjs.org/zh-cn/basics/extend.html

可以自定义一些方法,来扩展框架内已有的对象的功能,然后直接调用。
已有的对象包括:

  • Application
  • Context
  • Request
  • Response
  • Helper (类似工具方法)

helper

创建
\app\extend\helper.js

  1. module.exports = {
  2. a(){
  3. return "abc"
  4. }
  5. }

在其他文件内使用

  1. ctx.helper.a()

====================

请求、响应

image.png image.png

get

app/router.js 里面url

  1. module.exports = app => {
  2. const { router, controller } = app;
  3. router.get('/user', controller.home.testPwd);
  4. };

app/controller/home.js 控制器里面

  1. 'use strict';
  2. const Controller = require('egg').Controller;
  3. class HomeController extends Controller {
  4. async user(){
  5. const { ctx } = this;
  6. //get方法接收的参数,会通过下面ctx.quary传递
  7. var quary = ctx.query;
  8. console.log(quary);
  9. ctx.body = quary;
  10. }
  11. }
  12. module.exports = HomeController;

image.png

post

post方法
https://eggjs.org/zh-cn/core/httpclient.html#post

表单提交
https://eggjs.org/zh-cn/core/httpclient.html#form-%E8%A1%A8%E5%8D%95%E6%8F%90%E4%BA%A4

1、设置路由

要用post方法设置
image.png

2、控制器获取post数据

image.png
image.png

3、CSRF

cookie

image.png
image.png
image.png
image.png
image.png或者设置为空NULL

Session

image.png

image.png
image.png
image.png

image.png image.png
image.png
设置是完全基于cookie
image.png(不建议)
image.png(推荐)

=================

关系型数据库 egg-MySQL

https://eggjs.org/zh-cn/tutorials/mysql.html
https://github.com/eggjs/egg-mysql

1、安装插件

  1. npm i egg-mysql --save

2、启用插件

/config/plugin.js

  1. 'use strict';
  2. /** @type Egg.EggPlugin */
  3. module.exports = {
  4. // had enabled by egg
  5. // static: {
  6. // enable: true,
  7. // }
  8. mysql:{
  9. enable:true,
  10. package:'egg-mysql',
  11. }
  12. };

3、配置数据库信息

config/config.default.js

  1. /* eslint valid-jsdoc: "off" */
  2. 'use strict';
  3. /**
  4. * @param {Egg.EggAppInfo} appInfo app info
  5. */
  6. module.exports = appInfo => {
  7. /**
  8. * built-in config
  9. * @type {Egg.EggAppConfig}
  10. **/
  11. const config = exports = {};
  12. // use for cookie sign key, should change to your own and keep security
  13. config.keys = appInfo.name + '_1600680771247_3607';
  14. // add your middleware config here
  15. config.middleware = [];
  16. // add your user config here
  17. const userConfig = {
  18. // myAppName: 'egg',
  19. };
  20. //配置数据库信息
  21. config.mysql = {
  22. client: {
  23. // host
  24. host: '127.0.0.1',
  25. // 端口号
  26. port: '3306',
  27. // 用户名
  28. user: 'root',
  29. // 密码
  30. password: 'root',
  31. // 数据库名
  32. database: 'test',
  33. // 时区,重要,否则可能和数据库储存的date类型的时间不一致
  34. timezone: 'utc',
  35. },
  36. // 是否加载到 app 上,默认开启
  37. app: true,
  38. // 是否加载到 agent 上,默认关闭
  39. agent: false,
  40. }
  41. return {
  42. ...config,
  43. ...userConfig,
  44. };
  45. };

4、在service中使用

/app/service/home.js

  1. 'use strict';
  2. const Service = require('egg').Service;
  3. class homeService extends Service {
  4. //根据id查询用户
  5. async getUser(uid) {
  6. let userInfo = await this.app.mysql.get('user',{id:uid});
  7. return userInfo;
  8. };
  9. //查询所有用户
  10. async getAllUser() {
  11. let userInfo = await this.app.mysql.select('user');
  12. return userInfo;
  13. };
  14. //插入
  15. async insertUser(){
  16. let result = await this.app.mysql.insert('user', {
  17. id: null ,
  18. name:'xjt',
  19. sex:'man',
  20. psw:'888888'
  21. });
  22. //INSERT INTO `user` (`id`, `name`, `sex`, `psw`) VALUES (NULL, 'xjt', 'man', '888888')
  23. return result;
  24. };
  25. //修改
  26. async updateUser(){
  27. let result = await this.app.mysql.update('user', {
  28. id: 5 ,
  29. name:'xxxxx',
  30. sex:'xxxxx',
  31. psw:'123123'
  32. });
  33. //UPDATE `user` SET `name` = 'xjt', `sex` = 'man', 'psw' = '888888' WHERE id = 5 ;
  34. return result;
  35. };
  36. //删除
  37. async delUser(){
  38. let result = await this.app.mysql.delete('user', {id: 5});
  39. //DELETE FROM `user` WHERE `id` = '5';
  40. return result;
  41. };
  42. }
  43. module.exports = homeService;

拼接SQL语句

https://github.com/eggjs/egg-mysql#custom-literal
官方建议是使用Literal,可以看例子

5、调用

可以通过其他的服务 或者 控制器调用
/app/controller/home.js

  1. 'use strict';
  2. const Controller = require('egg').Controller;
  3. class HomeController extends Controller {
  4. async index() {
  5. const { ctx } = this;
  6. ctx.body = 'hi, egg';
  7. };
  8. //调用查询
  9. async getUser() {
  10. const { ctx } = this;
  11. let uid = this.ctx.params.id;
  12. if (uid > 0) {
  13. ctx.body = await this.service.home.getUser(uid);
  14. } else{
  15. ctx.body = await this.service.home.getAllUser();
  16. }
  17. };
  18. async insertUser(){
  19. const { ctx } = this;
  20. ctx.body = await this.service.home.insertUser();
  21. };
  22. //调用更新
  23. async updateUser(){
  24. const { ctx } = this;
  25. ctx.body = await this.service.home.updateUser();
  26. };
  27. //调用删除
  28. async delUser(){
  29. const { ctx } = this;
  30. ctx.body = await this.service.home.delUser();
  31. };
  32. }
  33. module.exports = HomeController;

6、配置路由

/app/router.js

  1. 'use strict';
  2. /**
  3. * @param {Egg.Application} app - egg application
  4. */
  5. module.exports = app => {
  6. const { router, controller } = app;
  7. router.get('/', controller.home.index);
  8. router.get('/getUser/:id', controller.home.getUser);
  9. router.get('/insertUser', controller.home.insertUser);
  10. router.get('/updateUser', controller.home.updateUser);
  11. router.get('/delUser', controller.home.delUser);
  12. };

==================

跨域 egg-cors

image.png
只要前端浏览器页面的协议、主机、端口,任意一个和后端服务器的不一致,就是跨域,浏览器就会触发保护。

前后端分离就会遇到上面的提示,不能直接访问服务器的数据,除非服务器设置请求来源的白名单’Access-Control-Allow-Origin’ ,让服务器知道哪些来源是开发者信任的,然后把这个信息放在响应头,传回给浏览器,才能成功交换数据。

1、安装插件

  1. npm i egg-cors --save

2、启用插件

位置: 项目app/config/plugin.js

  1. 'use strict';
  2. /** @type Egg.EggPlugin */
  3. module.exports = {
  4. // had enabled by egg
  5. // static: {
  6. // enable: true,
  7. // }
  8. mysql:{
  9. enable:true,
  10. package:'egg-mysql',
  11. },
  12. //启用跨域cors插件
  13. cors:{
  14. enable: true,
  15. package: 'egg-cors',
  16. }
  17. };

3、配置白名单

config/config.default.js

  1. /* eslint valid-jsdoc: "off" */
  2. 'use strict';
  3. /**
  4. * @param {Egg.EggAppInfo} appInfo app info
  5. */
  6. module.exports = appInfo => {
  7. /**
  8. * built-in config
  9. * @type {Egg.EggAppConfig}
  10. **/
  11. const config = exports = {};
  12. // use for cookie sign key, should change to your own and keep security
  13. config.keys = appInfo.name + '_1600680771247_3607';
  14. // add your middleware config here
  15. config.middleware = [];
  16. // add your user config here
  17. const userConfig = {
  18. // myAppName: 'egg',
  19. };
  20. config.mysql = {
  21. client: {
  22. // host
  23. host: '127.0.0.1',
  24. // 端口号
  25. port: '3306',
  26. // 用户名
  27. user: 'root',
  28. // 密码
  29. password: 'root',
  30. // 数据库名
  31. database: 'test',
  32. },
  33. // 是否加载到 app 上,默认开启
  34. app: true,
  35. // 是否加载到 agent 上,默认关闭
  36. agent: false,
  37. };
  38. //配置白名单
  39. config.cors = {
  40. origin: '*', //*号表示所有来源都是信任的
  41. allowMethods: 'GET,HEAD,PUT,POST,DELETE,PATCH' //表示允许通过左边的请求方法
  42. };
  43. return {
  44. ...config,
  45. ...userConfig,
  46. };
  47. };

配置好后,所有的前端请求都可以正常访问后端。

====================

防范 csrf

image.png
请求发现报403,原因是eggjs自带一个防止csrf 攻击,因此多了个需要配置csrf_token 的东西。
https://eggjs.org/zh-cn/core/security.html#%E5%AE%89%E5%85%A8%E5%A8%81%E8%83%81-ssrf-%E7%9A%84%E9%98%B2%E8%8C%83

如果不需要,可以关掉,因为前后端分离我们可以不通过这样来检查攻击,关掉后,真的可以正常通信了。

关闭csrf

config/config.default.js

  1. /* eslint valid-jsdoc: "off" */
  2. 'use strict';
  3. /**
  4. * @param {Egg.EggAppInfo} appInfo app info
  5. */
  6. module.exports = appInfo => {
  7. /**
  8. * built-in config
  9. * @type {Egg.EggAppConfig}
  10. **/
  11. const config = exports = {};
  12. // use for cookie sign key, should change to your own and keep security
  13. config.keys = appInfo.name + '_1606374315935_8008';
  14. // add your middleware config here
  15. config.middleware = [];
  16. // add your user config here
  17. const userConfig = {
  18. // myAppName: 'egg',
  19. };
  20. config.mysql = {
  21. client: {
  22. // host
  23. host: '111.230.149.73',
  24. // 端口号
  25. port: '3306',
  26. // 用户名
  27. user: 'ddUser',
  28. // 密码
  29. password: 'LS0A2g9CvBYmC78X',
  30. // 数据库名
  31. database: 'ddinvioce',
  32. },
  33. // 是否加载到 app 上,默认开启
  34. app: true,
  35. // 是否加载到 agent 上,默认关闭
  36. agent: false,
  37. };
  38. // 跨域
  39. config.cors = {
  40. origin: '*', //*号表示所有来源都是信任的
  41. allowMethods: 'GET,POST' //表示允许通过左边的请求方法
  42. };
  43. // 防范csrf
  44. config.security = {
  45. csrf: {
  46. enable:false, // 表示关掉csrf防范验证
  47. },
  48. };
  49. return {
  50. ...config,
  51. ...userConfig,
  52. };
  53. };

====================

NoSQL egg-redis

https://www.npmjs.com/package/egg-redis

在服务器内存开一个简单的数据库,专门存取简单的key : value,一般用于缓存,这里用于存储用户的token

1、安装插件

  1. npm i egg-redis --save

2、启用插件

/config/plugin.js

  1. 'use strict';
  2. /** @type Egg.EggPlugin */
  3. module.exports = {
  4. // had enabled by egg
  5. // static: {
  6. // enable: true,
  7. // }
  8. mysql:{
  9. enable:true,
  10. package:'egg-mysql',
  11. },
  12. cors:{
  13. enable: true,
  14. package: 'egg-cors',
  15. },
  16. exports.redis = {
  17. enable: true,
  18. package: 'egg-redis',
  19. };
  20. };

3、配置

/config/config.default.js

  1. module.exports = appInfo => {
  2. //其他配置
  3. //exports.XXXX = {};
  4. //启用egg-redis插件
  5. config.redis = {
  6. client: {
  7. port: 6379, // Redis 端口,默认6379
  8. host: '127.0.0.1', // Redis 数据库的主机
  9. password: 'auth', // Redis 数据库密码
  10. db: 0, // Redis 数据库名,一般就是0,多个数据库看官网配置
  11. },
  12. }
  13. return {
  14. ...config,
  15. ...userConfig,
  16. };
  17. }

4、使用

设置Key:Value

读取Value