egg学习笔记-1

news/2023/12/1 7:37:16

入门笔记

请按照官方文档初始化一个simple工程项目,按照如下步骤学习即可,如有不懂的请参考官方文档。

禁止csrf验证

根据如下步骤进行控制的创建,在执行Post操作的时候会出现invalid csrf token错误。需要禁止此特性。

创建路由

/**
 * @param {Egg.Application} app - egg application
 */
module.exports = app => {
  const {
    router,
    controller,
  } = app;
  router.get('/', controller.home.index);
  // 新建资源路由
  router.resources('SystemUser', '/system/user', controller.system.user);
};

控制器controller.system.user,对应的是controller目录下的system目录里面的user.js文件

创建对应的控制器

const Controller = require('egg').Controller;

class SystemUserController extends Controller {
  async index() {
    const {
      ctx,
    } = this;
    ctx.body = 'hello ! this is SystemUserController';
  }
}
module.exports = SystemUserController;  

访问地址:localhost:7001/system/user

创建可以提交数据的控制器方法

const Controller = require('egg').Controller;

class SystemUserController extends Controller {
  async index() {
    const {
      ctx,
    } = this;
    ctx.body = 'hello ! this is SystemUserController';
  }

  async create() {
    const ctx = this.ctx;
    const user = ctx.request.body;
    ctx.body = user;
  }
}

module.exports = SystemUserController;

POST方法访问网址:localhost:7001/system/user 会提示invalid csrf token错误。

关闭csrf验证

  // config\config.default.js
  // 关闭csrf验证
  config.security = {
    csrf: {
      enable: false,
    },
  };

开启验证

在上面的例子中,我们通过表单提交了任何数据,都会回显到界面上,如果是数据需要存储或者做其他业务处理,则需要对用户输入的数据进行验证。
egg提供了egg-validate插件进行表单验证

安装插件

cnpm install egg-validate --save

配置启用插件

/** @type Egg.EggPlugin */
module.exports = {
  // had enabled by egg
  // static: {
  //   enable: true,
  // }
  validate: {
    enable: true,
    package: 'egg-validate',
  },

};

使用验证组件

首先创建一个规则,这里我们定义username是字符串而且是必须的,最大长度为8个字符。
定义password为字符串且必须,最小长度为6个字符。
ctx.validate(createRule, ctx.request.body);
通过上述语句进行参数检查
更多规则请参考:https://github.com/node-modul...

const Controller = require('egg').Controller;

// 定义本接口的请求参数的验证规则
const createRule = {
  username: {
    type: 'string',
    required: true,
    max: 8,
  },
  password: {
    type: 'string',
    required: true,
    min: 6,
  },
};

class SystemUserController extends Controller {
  async index() {
    const {
      ctx,
    } = this;
    ctx.body = 'hello ! this is SystemUserController';
  }

  async create() {
    const ctx = this.ctx;
    // 验证输入参数是否符合预期格式
    ctx.validate(createRule, ctx.request.body);
    const user = ctx.request.body;
    ctx.body = user;
  }
}

module.exports = SystemUserController;

测试

使用POSTMAN提交任意字段,则会提示Validation Failed (code: invalid_param)
如何查看具体错误信息呢。下面将定义统一错误处理的中间件进行错误处理。


统一错误处理中间件

在项目的app目录中创建middleware目录,此目录中可以创建中间件。

创建错误处理中间件

'use strict';
module.exports = () => {
  return async function errorHandler(ctx, next) {
    try {
      await next();
    } catch (err) {
      // 控制台输出
      console.error('MiddleWare errorHandler', err);
      // 所有的异常都在 app 上触发一个 error 事件,框架会记录一条错误日志
      ctx.app.emit('error', err, ctx);
      // status 如果没有,则统一为500
      const status = err.status || 500;
      // 如果是500错误,且是生产环境,则统一显示“Internal Server Error”
      const error = status === 500 && ctx.app.config.env === 'prod' ? 'Internal Server Error' : err;
      // 改变上下文状态代码
      ctx.status = status;
      // 从 error 对象上读出各个属性,设置到响应中
      ctx.body = {
        error,
      };
    }
  };
};

启用中间件

文件configconfig.default.js中

  // add your middleware config here
  config.middleware = [];

将其修改为包含你创建的中间件

  // add your middleware config here
  // errorHandler 统一错误处理
  config.middleware = [ 'errorHandler' ];

  // errorHandler 只在/api上生效
  config.errorHandler = {
    match: '/api',
  };

如上所示,可以设置错误处理中间件在什么URL上面起作用。这里我们使用/api

测试路由

先使用原来的路由访问:localhost:7001/system/user
错误提示依旧
变更路由:打开文件:approuter.js

  // router.resources('SystemUser', '/system/user', controller.system.user);
  router.resources('SystemUser', '/api/v1/system/user', controller.system.user);

再次访问:localhost:7001/api/v1/system/user
提示信息会变成:

{"error":{"message":"Validation Failed","code":"invalid_param","errors":[{"message":"required","field":"username","code":"missing_field"},{"message":"required","field":"password","code":"missing_field"}]}}

格式化接口返回的数据结构

在上面显示错误信息中,可以看到规范的Json数据,如果开发接口,我们就需要定义统一的数据结构,以便客户端进行解析。
在API开发中,可以定义接口的标准返回格式。通过框架扩展方式定义返回数据格式是一个非常方便的方法。
在app目录中创建extend目录,对egg的内置对象Helper进行扩展即可。

创建Helper扩展

文件:app/extend/helper.js

'use strict';

module.exports = {
  /**
   * 调用正常情况的返回数据封装
   * @param {Object} ctx - context
   * @param {*} msg  - message
   * @param {*} data - 数据
   */
  success(ctx, msg, data) {
    ctx.body = {
      code: 0,
      msg,
      data,
    };
    ctx.status = 200;
  },

  /**
   * 处理失败,处理传入的失败原因
   * @param {*} ctx - context
   * @param {Object} res - 返回的状态数据
   */

  fail(ctx, res) {
    ctx.body = {
      code: res.code,
      msg: res.msg,
      data: res.data,
    };
    ctx.status = 200;
  },
};

改造统一错误处理

// 从 error 对象上读出各个属性,设置到响应中
// ctx.body = {
//   error,
// };
// 格式化返回错误信息
ctx.helper.fail(ctx, {
  code: status,
  msg: error.message,
  data: error.errors,
});

测试

再次访问:localhost:7001/api/v1/system/user
提示信息会变成:

{
    "code": 422,
    "msg": "Validation Failed",
    "data": [
        {
            "message": "required",
            "field": "username",
            "code": "missing_field"
        },
        {
            "message": "required",
            "field": "password",
            "code": "missing_field"
        }
    ]
}

将控制器user中的返回改为标准格式

async create() {
  const ctx = this.ctx;
  // 验证输入参数是否符合预期格式
  ctx.validate(createRule, ctx.request.body);
  const user = ctx.request.body;
  // ctx.body = user;
  this.ctx.helper.success(this.ctx, 'ok', user);
}

提交满足要求的数据,测试正确的返回数据
username testuser
password 1234567890
提交后将返回标准的数据格式

{
    "code": 0,
    "msg": "ok",
    "data": {
        "username": "testuser",
        "password": "1234567890"
    }
}

http://www.niftyadmin.cn/n/3114381.html

相关文章

DOM对象的事件

1. 监听input变化的事件,可参考:https://www.cnblogs.com/slongs/p/10557664.html A. onchange——在输入域的内容改变时触发; B. oninput——在用户输入时触发; C. onkeyup——在键盘按键被松开时触发; D. onkeydown—…

$.contents().find设置的data在iframe子页面无法获取值

<iframe src"iframe16.html" id"iframe16" name"iframe16"></iframe> document.frames只有IE、Opera浏览器支持&#xff0c;等同于window.frames&#xff0c;用来获取window对象的集合。而在Firefox、Chrome、Safari浏览器中使用doc…

利用Costura.Fody制作绿色单文件程序(C#程序(含多个Dll)合并成一个Exe)

利用Costura.Fody制作绿色单文件程序&#xff08;C#程序&#xff08;含多个Dll&#xff09;合并成一个Exe&#xff09; 原文:利用Costura.Fody制作绿色单文件程序&#xff08;C#程序&#xff08;含多个Dll&#xff09;合并成一个Exe&#xff09;开发程序的时候经常会引用一些第…

如何获得大学教材的PDF版本?

最近急需一本算法书的配套答案&#xff0c;这本配套单独出售&#xff0c;好像在市面上还买不到&#xff0c;在淘宝上搜索也只是上一个版本&#xff0c;并没有最新版本&#xff0c;让我很无奈。加上平时肯定会有这么一种情况&#xff0c;想看一些书&#xff0c;但买回来也看不了…

记一次CDH集群日志数据清理

背景 集群运行一段时间&#xff08;大概一月多&#xff09;后&#xff0c;cloudera manager管理界面出现爆红&#xff0c;爆红的组件有hdfs、zookeeper。 发现问题 点击详细内容查看&#xff0c;报日志空间不够的错误。初步判断是各个组件的日志数据把空间占满了。 查看各个目录…

python三大器(装饰器/生成器/迭代器)

1装饰器 1.1基本结构 def 外层函数(参数):def 内层函数(*args,**kwargs);return 参数(*args,**kwargs)return 内层函数 外层函数 def index()pass #示例: def func(arg):def inner():v arg()return v return inner func def index():print(123)return 666print(index) fu…

tp5时间格式转换

将时间戳变成时间格式输出到页面 public function index(){$this->assign(time, time());return $this->fetch();} 页面如果这样输出 <!-- 时间输出 --><h3>{$time}</h3> 输出结果是时间戳 想要输出正常时间格式可以这样填写 <!-- 时间输出 -->&…

【转】Mongodb常见错误 - child process failed, exited with error number

child process failed, exited with error number 1 child process failed, exited with error number 48 child process failed, exited with error number 100

spring-boot的access日志格式修改

前言 使用spring-boot框架开发的项目中&#xff0c;默认的logback格式可能默认是如下的格式&#xff1a; <Valve className"org.apache.catalina.valves.AccessLogValve" directory"logs" prefix"access." suffix".log" pattern&qu…

java学习基础部分

JVM虚拟机的位置&#xff1a; 垃圾回收在java程序运行过程中自动进行&#xff0c;程序员无法精准控制和干预。 Java程序还会出现内存泄漏和内存溢出。 Jre jvmjava se标准类库 Jdk jre 开发工具集 为什么需要配置path环境变量呢&#xff1f; 因为如果不配置我们只能在jre路径…

layui省市区下拉菜单三级联动

使用这个功能需要用到layui这个文件夹的内容&#xff0c;所以不能只把layui.css和layui.js引入&#xff0c;要从layui文件夹获取 显示效果 代码部分 <!DOCTYPE html> <html><head><meta charset"utf-8"><meta name"viewport" c…

1.17-1.18 rewrite实战

1.17-1.18 rewrite实战https://coding.net/u/aminglinux/p/nginx/git/blob/master/rewrite/example.md 转载于:https://blog.51cto.com/13578154/2308328

手把手教你造一个基于React的markdown编辑器

前言 笔者在18年年末的时候接到一个开发任务——搭建一个AI项目的开放平台&#xff0c;其中的产品文档为转化为HTML格式的markdown文档。考虑到文档的即时更新&#xff0c;将文档信息做成了Ajax接口的形式。因此管理后台只需将textarea表单的内容通过markdown解析器进行HTML格式…

原生js下拉菜单联动

原生的js联动 代码部分 <!DOCTYPE html> <html><head><meta charset"UTF-8"><title>联动</title><script type"text/javascript">function fn() {var select document.getElementById("type");var c…

推荐一款功能强大的Tomcat 管理监控工具,可替代Tomcat Manager

我们在本地启动Tomcat服务器后&#xff0c;用localhost&#xff1a;<默认端口>访问&#xff1a; 再点Manager App&#xff0c;即可进入Tomcat自带的Manager这个应用&#xff0c;此处可以单独部署/卸载每一个应用。可以看到在Manager应用里提供的功能是很有限的。 最近我在…

(二)lamp环境搭建之编译安装mysql

mysql 编译安装1&#xff0c;在网站上下载&#xff1a; wget http://dev.mysql.com/get/Downloads/MySQL-5.6/mysql-5.6.15.tar.gz 2&#xff0c;安装cmake yum安装即可。&#xff08;“CMake”这个名字是“cross platform make”的缩写,&#xff09; 3&#xff0c;cmake使用报…
最新文章