侧边栏壁纸
博主头像
小佑Blog| 小佑前端 | WEB前端博客 | WEB前端笔记 博主等级

未来属于那些相信梦想,并愿意为之付诸行动的人

  • 累计撰写 68 篇文章
  • 累计创建 91 个标签
  • 累计收到 67 条评论

目 录CONTENT

文章目录

egg.js

@小佑前端
2022-03-15 / 0 评论 / 1 点赞 / 2607 阅读 / 0 字 / 正在检测是否收录...

ExpressKoaNode.js社区广发使用的框架,简单且扩展性强,非常适合做个人项目,但框架本身缺少约定,标准的MVC模型会有各种千奇百怪的写法,Egg.js相比Express和Koa更规范一些,Egg.js按照规定进行开发,内置多进程管理,进行Koa开发,性能优异,具有高度可扩展的插件机制,框架稳定,并提供基于Egg.js定制上层框架的能力。
image.png

Egg.js基于Es6Es7以及TypescriptKoa2,使得Nodejs具有更规范的开发模式、更低的学习成本、更优雅的代码、更少的开发成本、更少的维护成本,它是为企业级框架而生!

##安装egg脚手架以及使用egg-init创建项目

方法一:

npm i egg-init -g

// egg-example 是项目名字
egg-init egg-example --type=simple

cd egg-example

npm i

运行项目:

npm run dev

方法二

mkdir egg-example && cd egg-example

npm init-egg --type=simple

npm i

运行项目:

npm run dev

Vscode插件egg

Egg Tools
可以是快速使用Egg.js语法,更加灵活使用
image.png

Egg-view-ejs

npm i egg-view-ejs --save
// 使用插件须在config/plugin.js进行配置

MVC框架

M:model模型(service) 和数据打交道(查询数据库/操作数据库/请求数据)处理复杂的业务逻辑以及数据操作

V:view视图 模板 页面的展示

C: controller控制器负责处理业务逻辑的处理 (简单业务员逻辑处理)

获取爬虫系统设计的API接口
新闻列表
新闻内容

项目目录概念

  • app

    • controller: 控制器 负责处理一些业务逻辑的处理
    • pubilc:放置静态资源文件
    • view: 视图 模板 页面的展示
    • service: (Model)模型主要和数据打交道(查询数据库 请求数据)
    • middleware: 中间件 处理路由配置之前和之后逻辑和一些权限处理
    • extend: 定义一些方法
    • router.js:存放路由配置

    image.png

controller

每一次用户请求,框架都会实例化对应的Service实例,由于它继承与egg.Service,故拥有下列属性方便我们进行开发

  • this.ctx:当前请求的上下文Context对象的实例,通过它我们可以拿到框架封装好的处理当前请求的各种便捷属性和方法
  • this.app: 当前应用Application对象的实例,通过它我们可以拿到框架提供的全局对象和方法
  • this.service: 应用定义的Service,通过它我们可以访问到抽象出的业务层,等价于this.ctx.service
  • this.config:应用运行时的配置
  • this.logger:logger 对象,上面有四个方法(debug, info, warn, error),分别代表打印四个不同的日志,使用方法和效果与content logger中介绍的一样,但是通过这个logger对象记录的日志,在日志前面会加上打印该日志的文件路径,以便快速定位日志打印位置

Service

Service文件必须放在 app/service 目录,可以支持多级目录,访问的时候可以通过名录名级联访问。

extend

egg框架会把app/extend/application.js中定义的对象与Koa Application的prototype对象进行合并,在应用启动时会基于扩展后的prototype生成app对象

middleware

匹配路有前、匹配路由完成做的一些列操作。Egg时基于Koa实现的,所以Egg的中间件形式和Koa的中间件是一样的,都是基于洋葱圈模型。

配置

一般来说中间件也会有自己的配置。在框架中,一个完整的中间件是包含了配置处理的。我们约定一个中间件是一个放置在 app/middleware 目录下的单独文件,它需要exports一个普通的function,接受两个参数:

  • options: 中间件的配置项,框架会将 app.config[${middlewareName}] 传递进来。
  • app: 当前应用 Application 的实例

CSRF

JSONP配置中,我们只需要打开csrf: true,即可对JSONP接口开启 CSRF 校验。

// config/config.default.js
module.exports = {
  jsonp: {
    csrf: true,
  },
};

注意,CSRF 校验依赖于 security 插件提供的基于 Cookie 的 CSRF 校验。

在开启 CSRF 校验时,客户端在发起 JSONP 请求时,也要带上 CSRF token,如果发起 JSONP 的请求方所在的页面和我们的服务在同一个主域名之下的话,可以读取到 Cookie 中的 CSRF token(在 CSRF token 缺失时也可以自行设置 CSRF token 到 Cookie 中),并在请求时带上该 token。

// 增加配置中间件
config.middleware = ['printdate', forbidip] // 这个时middleware目录下问文件名字,并非方法名字

// 给中间件传入参数
config.printdate = {
	a:"String",
	b:"Booleran"
}

ctx.cookies.set(key, value, options)

设置 Cookie 其实是通过在 HTTP 响应中设置 set-cookie 头完成的,每一个 set-cookie 都会让浏览器在Cookie中存一个键值对。在设置 Cookie 值的同时,协议还支持许多参数来配置这个Cookie的传输、存储和权限。

  • {Number} maxAge: 设置这个键值对在浏览器的最长保存时间。是一个从服务器当前时刻开始的毫秒数。

  • {Date} expires: 设置这个键值对的失效时间,如果设置了 maxAge,expires 将会被覆盖。如果 maxAge 和 expires 都没设置,Cookie 将会在浏览器的会话失效(一般是关闭浏览器时)的时候失效。

  • {String} path: 设置键值对生效的 URL 路径,默认设置在根路径上(/),也就是当前域名下的所有 URL 都可以访问这个 Cookie。

  • {String} domain: 设置键值对生效的域名,默认没有配置,可以配置成只在指定域名才能访问。

  • {Boolean} httpOnly: 设置键值对是否可以被 js 访问,默认为 true,不允许被 js 访问。

  • {Boolean} secure: 设置键值对只在 HTTPS 连接上传输,框架会帮我们判断当前是否在 HTTPS 连接上自动设置 secure 的值。
    除了这些属性之外,框架另外扩展了 3 个参数的支持:

  • {Boolean} overwrite:设置 key 相同的键值对如何处理,如果设置为 true,则后设置的值会覆盖前面设置的,否则将会发送两个 set-cookie 响应头。

  • {Boolean} signed:设置是否对 Cookie 进行签名,如果设置为 true,则设置键值对的时候会同时对这个键值对的值进行签名,后面取的时候做校验,可以防止前端对这个值进行篡改。默认为 true。

  • {Boolean} encrypt:设置是否对 Cookie 进行加密,如果设置为 true,则在发送 Cookie 前会对这个键值对的值进行加密,客户端无法读取到 Cookie 的明文值。默认为 false。
    在设置 Cookie 时我们需要思考清楚这个 Cookie 的作用,它需要被浏览器保存多久?是否可以被 js 获取到?是否可以被前端修改?

默认的配置下,Cookie是加签不加密的,浏览器可以看到明文,js 不能访问,不能被客户端(手工)篡改。

如果想要 Cookie 在浏览器端可以被 js 访问并修改:

ctx.cookies.set(key, value, {
  httpOnly: false,
  signed: false,
});

// 重新设置cookie的Key为null 也相当于清理Cookie
this.ctx.cookies(ket,null)

this.ctx.redirect('/index') // 路由跳转
  • Cookie可以实现 同一个浏览器访问同一个域的时候, 不同页面之间的数据共享
  • 实现数据的持久化 (关闭浏览器重新打开以后数据还存在)

Session

需要 特别注意 的是:设置 session 属性时需要避免以下几种情况(会造成字段丢失,

不要以 _ 开头
不能为 isNew
// ❌ 错误的用法

ctx.session._visited = 1; //    --> 该字段会在下一次请求时丢失
ctx.session.isNew = 'HeHe'; //    --> 为内部关键字, 不应该去更改

// ✔️ 正确的用法

ctx.session.visited = 1; //   -->  此处没有问题

Session的实现是基于Cookie的,默认配置下,用户 Session 的内容加密后直接存储在Cookie中的一个字段中,用户每次请求我们网站的时候都会带上这个 Cookie,我们在服务端解密后使用。Session的默认配置如下:

config.session = {
  key: 'EGG_SESS',
  maxAge: 24 * 3600 * 1000, // 1 天
  httpOnly: true,
  encrypt: true,
};

Session的使用方法非常直观,直接读取它或者修改它就可以了,如果要删除它,直接将它赋值为null

ctx.session = null;

语法

// 获取get传值
 cosnt qyery = this.ctx.query


// 获取动态路由传值
 const params = this.ctx.params


// 注意 ctx是异步
await this.ctx.render('index') // index:指的是你要渲染view文件下的名字 渲染view里面的模板视图
// <%=msg%>: 模板引擎

// app/service
var response = await this.ctx.curl(api, method) // 

// app/service
const Service = require('egg').Service;
class NewService extends Service {
	async getNewList() {
		const list = [1,2,3]
		
		return list
	}
}

image.png

一个控制器(controller)可以调用多个服务(service),服务(service)之间亦可以相互调用。

1
egg

评论区