1.创建项目
- 手动新建文件夹
- 执行
npm init egg --type=simple
- 运行项目
npm run dev
- hello world
'use strict';
const Controller = require('egg').Controller;
class HomeController extends Controller {
async index() {
const {
ctx } = this;
ctx.body = 'hello world';
}
}
module.exports = HomeController;
2.MVC概述
Egg中的控制器(controller)
- 直接响应数据或渲染模板
- 接受用户的输入
- 与路由建立对应关系
this.ctx可以获取到当前的上下文对象,通过此对象可以便捷的获取到请求与响应的属性与方法。
3.创建一个控制器
- 在controller文件夹下创建一个新文件fruits.js
const Controller = require("egg").Controller;
class FruitsController extends Controller{
async index(){
const {
ctx } = this;
ctx.body = "我是一个水果列表页面"
}
}
module.exports = FruitsController;
- 修改路由文件router.js
'use strict';
/**
* @param {Egg.Application} app - egg application
*/
module.exports = app => {
const {
router, controller } = app;
router.get('/', controller.home.index);
router.get('/fruits', controller.fruits.index);
};
- 页面访问
http://127.0.0.1:7002/fruits
4.路由传参
- 获取query参数
this.ctx.request.query
- 获取params参数
this.ctx.params.xxx
// query
-> `http://127.0.0.1:7002/fruits?index=1`
-> router.get('/fruits', controller.fruits.getId);
-> this.ctx.request.query = {
index:1 }
// params
-> router.get('/fruits/:id', controller.fruits.index);
-> http://127.0.0.1:7002/fruits/123
-> this.ctx.params.id = 123
5.表单提交
在controller中可以处理表单提交的数据。
获取post请求的参数:
this.ctx.request.body
CSRF指跨站请求伪造,Egg中对post请求做了一些安全验证,可以在config.default.js
文件中,通过下面的设置验证。
config.security = {
csrf:{
enable:false
}
}
6.Restful风格的URL定义
7.插件
- nunjucks模板插件
npm i egg-view-nunjucks -s
- egg-cors跨域请求配置插件
npm i egg-cors -s
- 在plugin.js文件中引入插件,在config.default.js中配置插件
'use strict';
/** @type Egg.EggPlugin */
module.exports = {
nunjucks:{
enable:true,
package:'egg-view-nunjucks'
},
cors:{
enable:true,
package:'egg-cors'
}
};
//config.default.js
config.view = {
defaultViewEngine:'nunjucks'
}
config.cors = {
origin:'*',
allowMethods:'GET,HEAD,PUT,POST,DELETE,PATCH'
}
- 在view目录中创建模板文件,并在控制器中使用render方法渲染模板。
5. 案例
'use strict';
const Controller = require('egg').Controller;
const fruitList = ["apple","banana","orange"]
class HomeController extends Controller {
async index() {
const {
ctx } = this;
await ctx.render("index",{
fruits:fruitList})
}
}
module.exports = HomeController;
// index.html
<body>
<h1>水果列表</h1>
<ul>
{
% for item in fruits %}
<li>{
{
item}}</li>
{
% endfor %}
</ul>
</body>
结果:
8. http协议
- 请求
(1) get
(2) post
(3) delete
(4) put
… - 响应
状态码: 200,404,500…
数据:json格式… - 服务器如何识别用户
(1) 使用cookie与session识别用户.
(2) 使用JWT(JSON WEB TOKEN)识别用户.
9.使用session识别用户
- 首页
<body>
<h1>首页</h1>
<form action="/logout" method="POST">
<button>注销登录</button>
</form>
</body>
- 登录页
<body>
<h2>login</h2>
<form action="/login" method="POST">
<input type="text" name="user">
<input type="text" name="password">
<button>登录</button>
</form>
</body>
- 路由
router.get('/', controller.home.index);
router.get('/login', controller.home.login);
router.post('/login', controller.home.doLogin);
router.post('/logout', controller.home.logout);
- controller
class HomeController extends Controller {
async index() {
const {
ctx } = this;
if(this.ctx.session.user){
await ctx.render("index",{
fruits:fruitList})
} else {
ctx.redirect("/login")
}
}
async login() {
const {
ctx } = this;
await ctx.render("login")
}
async doLogin() {
const {
ctx } = this;
let username = ctx.request.body.user;
let password = ctx.request.body.password;
if(username === '111' && password==="111"){
ctx.session.user = username;
ctx.redirect("/")
} else {
ctx.redirect("/login")
}
}
async logout(){
this.ctx.session.user = ""
this.ctx.redirect("/")
}
}
10.使用JWT识别用户
- 安装egg-jwt插件:
npm install --save egg-jwt
- 在plugin.js中引入插件
jwt:{
enable:true,
package:“egg-jwt”
}, - 配置config.default.js文件,设置secret;注意,secret不能泄露.
config.jwt={
secret:“fggfjkgsdfjkgjsklagdfjkl”
}
验证流程:
- 根据用户信息,生成
token
,并响应给客户端.let token = app.jwt.sign(user,app.config.jwt.secret)
- 客户端存储在
localstorage
中. - 客户端每次请求数据,请求头携带
token
. - 服务器接收请求,验证请求头的
token
,验证成功则响应数据.
let token = ctx.request.header.token
,
let decode = app.jwt.verify(token,app.config.jwt.secret)
- 前端页面刷新:location.reload
11.一些主要语法
- 获取请求参数
ctx.request.body.user
- 渲染页面
await ctx.render("login")
- 重定向
ctx.redirect("/login")