当前位置: 首页 > 工具软件 > Egg.js > 使用案例 >

后端——egg.js是什么、egg.js安装、约定规则、路由Router、控制器Controller、跨域

公孙巴英
2023-12-01

目录

一、egg.js是什么

二、egg安装

三、约定规则

四、路由Router

五、控制器Controller

六、跨域

1.egg-cors

1.下载

 2.开启插件

3.配置插件

4.使用:

2.实现jsonp接口

3.代理 egg中的网络请求技术:


EGG官网,可供后面查阅:教程 - Egg

一、egg.js是什么

  1. egg.js 是『约定优先于配置』的一个 Node.js web 框架

  2. Egg 奉行『约定优于配置』,按照一套统一的约定进行应用开发,团队内部采用这种方式可以减少开发人员的学习成本,开发人员不再是『钉子』,可以流动起来。没有约定的团队,沟通成本是非常高的,比如有人会按目录分栈而其他人按目录分功能,开发者认知不一致很容易犯错。但约定不等于扩展性差,相反 Egg 有很高的扩展性,可以按照团队的约定定制框架。使用 Loader 可以让框架根据不同环境定义默认配置,还可以覆盖 Egg 的默认约定。

  3. Express的原班人马打造了Koa,阿里在Koa的基础之上封装出Egg,框架的命名和功能符合阿里的企业文化:egg直译为鸡蛋,轻量简洁,功能齐全,免费开源,具备一个完整生命的所有特征,为孵化伟大的互联网企业而生。

二、egg安装

1、使用脚手架快速创建项目 ,小黑窗输入:npm init egg --type=simple

(上面指令输了,就会创建很多东西,比如:app config test .autod README.md等等)

2、输入指令:npm i

2.1如果卡住了,点小黑窗,按回车

2.2如果丢包了,就可以多次输入指令:npm i

2.3如果还是丢包了,就把node_modules删了,再npm i  (因为package.json在,它会根据里面的信息进行下载)

2.4也可以把以前用过的文件直接压缩过后拿过来,更改相应的信息就可以了

3、启动项目:npm run dev   或者  egg-bin dev

(这个是在package.json文件里面写的 "dev":"egg-bin dev")

4、浏览器访问: http://localhost:7001

上面启动后,就需要取访问。

网址可以多种写法:

http://127.8.0.0.1:7001  或者 

http://localhost:7001

或者  自己的网址 : http://192.168.1.6:7001

注:如果安装指令没有报错,运行报错一般就是网络卡,防火墙等原因导致丢包了,删除整个项目文件夹,重新安装项目即可

三、约定规则

1 app/router.js:用于配置URL路由规则;

2 app/controller/** :用于解析用户的输入,处理后返回相应的结果;

3 app/service/: 用于编写业务逻辑层;

4 app/public/: 用于放置静态资源;

5 config/config.{env}.js: 用于编写配置文件;

6 config/plugin.js 用于配置需要加载的插件;

四、路由Router

路由器:用户把数据发送给了路由器,路由器根据用户的需求

路由:描述请求URL和具体承担执行动作的Controller的对应。

(就是用户访问不同的路径时应该有不同的Controller去响应不同的内容,就是不同的网址去执行不同的分支或者程序)

注册后端的路由:

router.get('/getdata', controller.form.get);
//静态路由,也就是调用controller文件下的form文件里的get方法  

router.post('/home', controller.home.ajax1);

注意点:

1、顺序是:用户网址请求(无论地址栏 还是ajax)

==> 然后去 public(静态文件)找,

==>再找路由里的(路由里面也是按照顺序匹配的)

2、注册路由时,路由名不要跟静态文件名冲突,不然会优先访问静态资源

3、如果router里面注册了两个相同的名字,但是对应执行的函数不同,最终会执行先注册的

4、如果router里面写了*==> router.get('*', controller.home.all);

意思是不管输什么都不会有404了,如果把这个放在最前面,后面写的就不会被匹配到,所以一般*写在最后一句。但是不影响静态的网址,就是public里面的。因为public优先于router.js

例子:

app/router.js

'use strict';
/**
 * @param {Egg.Application} app - egg application
 */
module.exports = app => {
  const { router, controller } = app;
  router.get('/', controller.home.fn);
};


app/controller/home.js

class类里面可以写constructure,不写就有一个默认有一个空的对象 ,对象里面其中有一个功能ctx(context的缩写)  

this.ctx里面有一个功能body ==>如果将this.ctx.body设置了一个值,它会自动监听到body的值发生变化,它就会调end函数,传给前端。而且在取出body值的时候,会自动转为JSON数据。所以可以赋值任何类型的值

(this.ctx就是Controller提供的功能  主要就是使用它提供的:给前端发送数据,访问插件功能)

'use strict';  //严格模式
const Controller = require('egg').Controller; //这是commonjs,不属于ES6
//以下是ES6  extends是继承,Controller是官方的功能。HomeController是继承官方的功能
class HomeController extends Controller {  //HomeController这是类名,可自己取,首字母一般大写
  async fn() {
    const { ctx } = this;
    ctx.body = 'hi, egg';
    ctx.body = [1,2];  //这行代码不会运行了,上面一行的代码只会执行一次就断开网络连接
  }
}
//以下是commonjs
module.exports = HomeController;  //导出

五、控制器Controller

Controller负责解析用户的输入,处理后返回响应的结果。

1.所有的Controller 文件都必须放在 app/controller目录下

2.支持多级目录,访问时可以通过目录名级联访问。

例子:
如果router.js是:
router.get('/hello', controller.user.news)
则控制器对应:
在controller文件夹下有一个user文件中有一个news方法
当用户访问的pathname为'/hello' 时  后端就会执行controller文件夹中的user.js文件中的news函数

六、跨域

1.egg-cors

框架提供了 egg-cors 插件来实现cors跨域请求。

1.下载

小黑窗指令 ==> cnpm i --save egg-cors
(也可以写:npm i egg-cors)

cnpm就是在淘宝下载 (丢包了只能删了重新下)

npm是在国外下载,会慢一点 (丢包率稍微小一点,而且丢包了可以再继续下)

--save就是下载到依赖项,可以不写

 2.开启插件

在config/plugin.js文件  (config配置,plugin插件)

 cors:{    enable: true,    package: 'egg-cors', }

'use strict';
/** @type Egg.EggPlugin */
module.exports = {
   cors:{
      enable: true,
      package: 'egg-cors',
    }
};

3.配置插件

  config/config.default.js文件  

	config.cors = {
		origin: '*',
		allowMethods: 'GET,HEAD,PUT,POST,DELETE,PATCH'
	}

默认origin只支持一个域名或者*表示全部,如果想支持具体的多个指定域名可以如下设置:

	config.cors = {
		// origin: ['http://localhost'],
		origin: function (ctx) { //设置允许来自指定域名请求
			console.log(ctx);
			const whiteList = ['http://www.baidu.com', 'http://www.hqyj.com']; //放白名单
			let url = ctx.request.header.origin;
			if (whiteList.includes(url)) {
				return url;
			}
			return 'http://localhost' //默认允许本地请求可跨域
		},
		allowMethods: 'GET,HEAD,PUT,POST,DELETE,PATCH'
	};

4.使用:

router.js文件 ==>router.get('/cors',controller.home.cors)

home.js文件 ==>async cors(){    this.ctx.body={info:"这个接口可以通过跨域访问"} }

 5. 注意:
跨域前端请求时需要携带跨域凭证,不然缓存会失效
​
前端网络请求时配置:
原生ajax:
xhr.withCredentials = true;
​
axios:
axios.post(url,{},{withCredentials:true}).then((res)=>{})
​
    
后端配置:
     config.cors = {
        origin: '具体的ip和端口 不能写* ',
        credentials:true  
  }

2.实现jsonp接口

方法一:
如果前端的参数中有cb=fn参数(jsonp接口参数),将会返回JSONP格式的数据,否则返回JSON格式的数据。
​
1.配置:config/config.default.js文件
config.jsonp = {
  callback: 'cb', // 识别 query 中的 `cb` 参数
  limit: 100, // 函数名最长为 100 个字符
};
2.写接口app/router.js==>
module.exports = app => {
  const jsonp = app.jsonp();
  app.router.get('/api/posts', jsonp, app.controller.posts.list);
};

方法二:

也可以直接在jsonp方法中直接配置,功能一样:

如果前端的参数中有cb=fn参数(jsonp接口参数),将会返回JSONP格式的数据,否则返回JSON格式的数据。app/router.js文件==>

	module.exports = app => {
		const jsonp = app.jsonp({
			callback: 'cb',  //JSONP的接口
			limit: 100,
		});
		app.router.get('/api/posts', jsonp, app.controller.posts.list);
	};

3.代理 egg中的网络请求技术:

this.ctx.curl(url, option)

option常用配置:

method:'GET/POST'

data:{name:"karen"} //会自动字符串化

返回promise对象

home.js文件 ==>

async cors(){
    let data1=await this.ctx.curl("http://www.baidu.com",{method:"GET",data:{pwd:123}})
    this.ctx.body=data1
}

例子:

1、index.js中:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src='https://s1.pstatp.com/cdn/expire-1-M/axios/0.19.2/axios.js'></script>
	</head>
	<body>
		<h1>ajax</h1>
		<button onclick="fn()">请求sina</button>
		<script>
			function fn() {
				var url = "http://192.168.6.60:7001/sina"
				axios(url)
					.then(res => console.log(res))
			}
		</script>
	</body>
</html>

2、rouer.js中:

'use strict';
/**
 * @param {Egg.Application} app - egg application
 */
module.exports = app => {
	const {
		router,
		controller		
	} = app;
	router.get('/sina', controller.home.sina);
};

3、app的controller的home.js中:

'use strict';
const Controller = require('egg').Controller;
class MyController extends Controller {
  async sina(){
	//url是新浪的数据
	//curl是window自带的网络工具,它集成答上下文对象中了
		var url="https://api.weibo.com/2/statuses/home_timeline.json?access_token=2.00ZmCkcDlel8HDd856f9b9ccsVwsYD"
		let res=await this.ctx.curl(url)  //this.ctx.curl(url)它的返回值是promise对象,所以用await取值
		this.ctx.body=res.data.toString()  //res.data是buffer类型
  }
}
module.exports = MyController;

 类似资料: