Egg.js 是为企业级框架和应用而生的,希望由 Egg.js 孕育出更多上层框架,帮助开发团队和开发人员降低开发和维护成本
注意:Egg.js 缩写为 Egg,我们平常所说的egg就是egg.js
Egg 的插件机制有很高的可扩展性,一个插件只做一件事,Egg 通过框架聚合这些插件,并根据自己的业务场景定制配置,这样应用的开发成本就变得很低
Egg 奉行『约定优于配置』,按照一套统一的约定进行应用开发,团队内部采用这种方式可以减少开发人员的学习成本,但约定不等于扩展性差,相反 Egg 有很高的扩展性,可以按照团队的约定定制框架。使用 Loader 可以让框架根据不同环境定义默认配置,还可以覆盖 Egg 的默认约定
推荐直接使用脚手架,只需几条简单指令,即可快速生成项目,免去了许多自己安装的麻烦,也不会出现因为安装失误而导致的环境集成失败
先建一个目录,用于安装环境的
mkdir egg-example && cd egg-example
快速安装egg框架,一般我们都直接用simple,就不需要自己去写骨架了
npm init egg --type=simple
除了simple还有一下几种安装的可选项
simple 简单 egg 应用程序骨架
empty 空的 egg 应用程序骨架
plugin egg plugin 骨架
framework egg framework 骨架
安装所需的模块,会根据 package.json 文件里的信息去自动安装我们需要的所有模块
npm i
安装完成后就可以启动项目了,启动都是在小黑窗里面启动哦
启动命令:npm run dev
然后去浏览器访问: http://localhost:7001,测试一下安装的环境有没有什么问题
注意:如果安装指令没有报错,运行报错一般就是网络卡了绘制防火墙没关又或者你电脑里安装的一些安全软件阻止了一些文件的运行等等原因导致丢失了数据包,遇到这种情况就直接删除整个项目文件夹,重新安装项目即可
Router 主要用来描述请求 URL 和具体承担执行动作的 Controller 的对应关系, 框架约定了 app/router.js 文件用于统一所有路由规则
通过统一的配置,我们可以避免路由规则逻辑散落在多个地方,从而出现未知的冲突,集中在一起我们可以更方便的来查看全局的路由规则
路由:指不同的网址去执行不同的分支或者程序
在app/router.js 里面定义 URL 路由规则
module.exports = app => {
const { router, controller } = app;
router.get('/home', controller.user.info);
};
app/controller 目录下面实现 Controller
class UserController extends Controller {
async info() {
const { ctx } = this;
ctx.body = 'hi, user
';
}
}

下面是路由的完整定义,参数可以根据场景的不同,可以自由选择:
router.verb('path-match', app.controller.action);
router.verb('router-name', 'path-match', app.controller.action);
router.verb('path-match', middleware1, ..., middlewareN, app.controller.action);
router.verb('router-name', 'path-match', middleware1, ..., middlewareN, app.controller.action);
路由完整定义主要包括5个主要部分:
注意:注册路由时 路由名不要跟静态文件名冲突 不然会优先访问静态资源
router.get(“/*”,controller.home.all); 当使用 *号时,表示与所以的网址适配,因此这个应该写在最后一个位置,不然随便输入什么就与之适配了,就不会匹配到对应的网址请求来的数据了
注册了两个相同的路由,只能访问到第一个
Controller 负责解析用户的输入,处理后返回相应的结果
Controller 层主要对用户的请求参数进行处理(校验、转换),然后调用对应的 service 方法处理业务,得到业务结果后封装并返回:
所有的Controller 文件都必须放在 app/controller目录下
支持多级目录,访问时可以通过目录名级联访问
module.exports = app => {
const {router,controller } = app;
router.get('/ajax1/fn', controller.home.ajax1);
router.get('/caradd', controller.car.add);
}

浏览器判断跨域为简单请求时候,会在Request Header中添加 Origin 字段 , 它表示我们的请求源,CORS服务端会将该字段作为跨源标志
CORS接收到此次请求后 , 首先会判断Origin是否在允许源(由服务端决定)范围之内,如果验证通过,服务端会在Response Header 添加 Access-Control-Allow-Origin、Access-Control-Allow-Credentials等字段
浏览器收到Respnose后会判断自己的源是否存在 Access-Control-Allow-Origin允许源中,如果不存在,会抛出“同源检测异常”
当跨域为简单请求时只需要CORS服务端在接受到携带Origin字段的跨域请求后,在response header中添加Access-Control-Allow-Origin等字段给浏览器做同源判断就可以了
但我们使用框架,这些底层代码就会被封装起来,我们也看不到底层代码,只要了解他们是怎么回事,知道在框架中该怎么用axios,jsonp和代理服务就可以了
html文件
axios的引入可以自己去官网下载也可以去引入,在上一篇文章里已经讲过,不会可以去看看
<h1>ajaxh1>
<button onclick="fn()">请求button>
<script src='https://s1.pstatp.com/cdn/expire-1-M/axios/0.19.2/axios.js'>script>
<script>
function fn(){
axios("http://192.168.43.132:7001/ajax1")
.then(res=>console.log(res))
}
script>
router.js文件
module.exports = app => {
const { router, controller } = app;
router.get('/ajax1', controller.home.ajax1);
};
controller/home.js 文件
class MyController extends Controller {
async ajax1(){
this.ctx.body={info:"ajax接口的数据",code:123456}
}
}
module.exports = MyController;

router.js文件
module.exports = app => {
router.get('/jsonp',app.jsonp(), controller.home.jsonp);
};
controller/home.js 文件
class MyController extends Controller {
async jsonp() {
this.ctx.body = {
info: "json接口的数据",
code: 20001
}
}
}
module.exports = MyController;

代理服务:我们自己前端直接请求别的服务的数据会有跨域限制,所以我们自己的前端请求自己的后端服务器,然后后端的服务器在用require请求别的服务器,别的服务器把数据传给我们的后端,我们的后端再把数据传给我们自己的前端,前端在操作数据写入页面,我们的后端服务器就叫做代理服务器
router.js文件
module.exports = app => {
router.get('/baidu', controller.home.baidu);
};
controller/home.js 文件
class MyController extends Controller {
async baidu(){
var url = "http://www.baidu.com";
let res=await this.ctx.curl(url)
this.ctx.body=res.data
}
}
module.exports = MyController;

GET请求传参数给后端
参数会拼接到url中
它的特点是速度快,但是不安全
后端返回的数据 前端是xhr对象接受了,并用js语言来使用返回数据
html文件
<h1>get请求h1>
<input type="text" id="seariput">
<button onclick="fn()">搜索button>
<script>
function fn() {
var searvalue=document.getElementById("seariput").value
var xhr=new XMLHttpRequest()
var url=`http://192.168.43.132:7001/get1?count=20&keywords=${searvalue}`
xhr.open("GET",url)
xhr.send()
xhr.onreadystatechange=()=>{
if(xhr.readyState==4&&xhr.status==200){
console.log(xhr.responseText)
}
}
}
script>
router.js文件
module.exports = app => {
router.get('/get1', controller.home.get1);
};
controller/home.js 文件
class MyController extends Controller {
async get1() {
var k = this.ctx.request.query
console.log(k)
this.ctx.body = {
info: "get1接口的数据"
}
}
}
module.exports = MyController;

html文件
<h1>get请求h1>
<input type="text" id="seariput">
<button onclick="fn()">搜索button>
<script src='https://s1.pstatp.com/cdn/expire-1-M/axios/0.19.2/axios.js'>script>
<script>
function fn() {
var searvalue=document.getElementById("seariput").value
var url=`http://192.168.43.132:7001/get1`
axios(url,{params:{count:30,keyw:searvalue}})
.then(res=>console.log(res))
}
script>
router.js文件
module.exports = app => {
router.get('/get1', controller.home.get1);
};
controller/home.js 文件
class MyController extends Controller {
async get1() {
var k = this.ctx.request.query
console.log(k)
this.ctx.body = {
info: "get1接口的数据"
}
}
}
module.exports = MyController;

html文件
<form method="GET" action="http://192.168.43.132:7001/login" target="_blank">
<input type="text" name="aaa"><br>
<input type="text" name="bbb"><br>
<input type="submit" value="login"><br>
form>
router.js文件
module.exports = app => {
router.get("/login",controller.home.login)
};
controller/home.js 文件
class MyController extends Controller {
async login(){
var k = this.ctx.request.query
console.log(k)
this.ctx.body="登陆成功"
}
}
module.exports = MyController;

当用户有隐私数据需要传输的时候,我们应该用POST请求,因为post请求在传输过程中会进行加密处理,不会向get一样直接拼接到地址栏中,更加安全,但是传输速度没有get快
如果有"大量"的数据发给后端 也要用POST请求
html文件
<h1>post请求h1>
账号:<input type="text" id="userid"> <br>
密码:<input type="text" id="pwd"><br>
<button onclick="fn()">登录button>
<script>
function fn(){
var userid = document.querySelector("#userid");
var pwd = document.querySelector("#pwd");
var xhr=new XMLHttpRequest()
var url="http://192.168.43.132:7001/post1"
xhr.open("POST",url,true)
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xhr.send(`userid=${userid.value}&pwd=${pwd.value}`)
xhr.onreadystatechange=function(){
if(xhr.readyState==4&&xhr.status==200){
console.log(xhr.responseText)
}
}
}
script>
router.js文件
module.exports = app => {
router.post('/post1', controller.home.post1);
};
controller/home.js 文件
class MyController extends Controller {
async post1() {
let obj=this.ctx.request.body
let query=this.ctx.request.query
console.log(obj,query)
this.ctx.body={info:"登录成功",res:obj}
}
}
module.exports = MyController;
