egg框架学习笔记
1、安装
npm i egg-init -g
egg-init egg-example --type=simple
cd egg-example
yarn install
npm run dev //localhost:7001
2、多环境配置
config
|- config.default.js
|- config.prod.js
|- config.test.js
|- config.local.js
config.default.js 为默认的配置文件,所有环境都会加载这个配置文件,开发环境config.local.js会覆盖不是合并default配置,测试线上配置同理
配置写法:返回一个对象;写成 exports.key = value 形式;返回一个function
// 将 logger 目录放到代码目录下
const path = require('path');
module.exports = appInfo => {
return {
logger: {
dir: path.join(appInfo.baseDir, 'logs'),
},
};
};
appInfo 说明
pkg package.json
name 应用名,同 pkg.name
baseDir 应用代码的目录
HOME 用户目录,如 admin 账户为 /home/admin
root 应用根目录,只有在 local 和 unittest 环境下为 baseDir,其他都为 HOME。
3、middleware
3.1、exports 一个普通的 function
module.exports = options => {
return async function xxx(ctx,next){
await next();
xxxx
}
}
3.2 使用中间件
在应用中比如config.default.js使用中间件
config.middleware = [ 'authority' ];
在框架或者插件中使用中间件
// app.js
module.exports = app => {
// 在中间件最前面统计请求时间
app.config.coreMiddleware.unshift('report');
};
应用层定义的中间件(app.config.appMiddleware)和框架默认中间件(app.config.coreMiddleware)都会被加载器加载,并挂载到 app.middleware 上。
路由中也可以使用中间件
// app/controller/search.js
exports.index = async ctx => {
ctx.body = `search: ${ctx.query.name}`;
};
// app/middleware/uppercase.js
module.exports = () => {
return async function uppercase(ctx, next) {
ctx.query.name = ctx.query.name && ctx.query.name.toUpperCase();
await next();
};
};
// app/router.js
module.exports = app => {
app.router.get('s', '/search', app.middleware.uppercase(), app.controller.search)
};
4、路由
重定向
//内部重定向
// app/router.js
module.exports = app => {
app.router.get('index', '/home/index', app.controller.home.index);
app.router.redirect('/', '/home/index', 302);
};
// app/controller/home.js
exports.index = async ctx => {
ctx.body = 'hello controller';
};
//外部重定向
// app/router.js
module.exports = app => {
app.router.get('/search', app.controller.search.index);
};
// app/controller/search.js
exports.index = async ctx => {
const type = ctx.query.type;
const q = ctx.query.q || 'nodejs';
if (type === 'bing') {
ctx.redirect(`http://cn.bing.com/search?q=${q}`);
} else {
ctx.redirect(`https://www.google.co.kr/search?q=${q}`);
}
};
5、controller
this.ctx: 当前请求的上下文 Context 对象的实例,通过它我们可以拿到框架封装好的处理当前请求的各种便捷属性和方法。
this.app: 当前应用 Application 对象的实例,通过它我们可以拿到框架提供的全局对象和方法。
this.service:应用定义的 Service,通过它我们可以访问到抽象出的业务层,等价于 this.ctx.service 。
this.config:应用运行时的配置项。
this.logger:logger 对象,上面有四个方法(debug,info,warn,error),分别代表打印四个不同级别的日志,使用方法和效果与 context logger 中介绍的一样,但是通过这个 logger 对象记录的日志,在日志前面会加上打印该日志的文件路径,以便快速定位日志打印位置。
5.1 类的写法
const Controller = require('egg').controller
class PostController extends Controller {
async create (){
const {ctx,service}=this;
let data = await ctx.service.postService.post();
await ctx.render('/index', data);
}
}
5.2 获取 HTTP 请求参数
1、query
在 URL 中 ? 后面的部分是一个 Query String,这一部分经常用于 GET 类型的请求中传递参数。例如 GET /posts?category=egg&language=node 中 category=egg&language=node 就是用户传递过来的参数。我们可以通过 ctx.query 拿到解析过后的这个参数体
2、params
route里面的参数
// app.get('/projects/:projectId/app/:appId', 'app.listApp');
// GET /projects/1/app/2
this.ctx.params.projectId //1
this.ctx.params.appId //2
3、body
ctx.request.query.id 和 ctx.query.id 是等价的,ctx.response.body= 和 ctx.body= 是等价的。
ctx.status === ctx.response.status
ctx.url === ctx.request.url
4、header
ctx.headers,ctx.header,ctx.request.headers,ctx.request.header:这几个方法是等价的,都是获取整个 header 对象。
ctx.get(name),ctx.request.get(name):获取请求 header 中的一个字段的值,如果这个字段不存在,会返回空字符串。
我们建议用 ctx.get(name) 而不是 ctx.headers['name'],因为前者会自动处理大小写。
5、cookie
保存后端header里的set-cookie
if (result.headers['set-cookie']) ctx.set('set-cookie', result.headers['set-cookie']);
自己设置浏览器cookie
如果想要 Cookie 在浏览器端可以被 js 访问并修改:
ctx.cookies.set(key, value, {
httpOnly: false,
signed: false,
});
如果想要 Cookie 在浏览器端不能被修改,不能看到明文:
ctx.cookies.set(key, value, {
httpOnly: true, // 默认就是 true
encrypt: true, // 加密传输
});
6、session
6、Service
处理业务逻辑
// app/service/user.js
const Service = require('egg').Service;
class UserService extends Service {
async find(uid) {
// 假如 我们拿到用户 id 从数据库获取用户详细信息
const user = await this.ctx.db.query('select * from user where uid = ?', uid);
return {
name: user.user_name,
age: user.age
};
}
}
module.exports = UserService;