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


    目录

    一、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

    1. 'use strict';
    2. /**
    3. * @param {Egg.Application} app - egg application
    4. */
    5. module.exports = app => {
    6. const { router, controller } = app;
    7. router.get('/', controller.home.fn);
    8. };

    app/controller/home.js

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

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

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

    1. 'use strict'; //严格模式
    2. const Controller = require('egg').Controller; //这是commonjs,不属于ES6
    3. //以下是ES6 extends是继承,Controller是官方的功能。HomeController是继承官方的功能
    4. class HomeController extends Controller { //HomeController这是类名,可自己取,首字母一般大写
    5. async fn() {
    6. const { ctx } = this;
    7. ctx.body = 'hi, egg';
    8. ctx.body = [1,2]; //这行代码不会运行了,上面一行的代码只会执行一次就断开网络连接
    9. }
    10. }
    11. //以下是commonjs
    12. 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', }

    1. 'use strict';
    2. /** @type Egg.EggPlugin */
    3. module.exports = {
    4. cors:{
    5. enable: true,
    6. package: 'egg-cors',
    7. }
    8. };

    3.配置插件

      config/config.default.js文件  

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

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

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

    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文件
    
    1. config.jsonp = {
    2.  callback: 'cb', // 识别 query 中的 `cb` 参数
    3.  limit: 100, // 函数名最长为 100 个字符
    4. };
    2.写接口app/router.js==>
    
    1. module.exports = app => {
    2.  const jsonp = app.jsonp();
    3.  app.router.get('/api/posts', jsonp, app.controller.posts.list);
    4. };

    方法二:

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

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

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

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

    this.ctx.curl(url, option)

    option常用配置:

    method:'GET/POST'

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

    返回promise对象

    home.js文件 ==>

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

    例子:

    1、index.js中:

    1. html>
    2. <html>
    3. <head>
    4. <meta charset="utf-8">
    5. <title>title>
    6. <script src='https://s1.pstatp.com/cdn/expire-1-M/axios/0.19.2/axios.js'>script>
    7. head>
    8. <body>
    9. <h1>ajaxh1>
    10. <button onclick="fn()">请求sinabutton>
    11. <script>
    12. function fn() {
    13. var url = "http://192.168.6.60:7001/sina"
    14. axios(url)
    15. .then(res => console.log(res))
    16. }
    17. script>
    18. body>
    19. html>

    2、rouer.js中:

    1. 'use strict';
    2. /**
    3. * @param {Egg.Application} app - egg application
    4. */
    5. module.exports = app => {
    6. const {
    7. router,
    8. controller
    9. } = app;
    10. router.get('/sina', controller.home.sina);
    11. };

    3、app的controller的home.js中:

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

  • 相关阅读:
    C语言:数组名和数组地址
    Python中2种常用数据可视化库:Bokeh和Altair
    【App自动化测试】(三)使用Appium进行自动化用例录制
    并发调用deepseek API,构建多轮对话数据
    在两台CentOS 7服务器上部署MinIO集群。
    第一次部署机器学习模型
    网络协议--DNS:域名系统
    【模糊控制】用模糊PID控制四轴机械臂轨迹跟踪运动
    Spring AOP 使用详解及源码分析
    策 略 模 式「指 鼠 为 鸭」
  • 原文地址:https://blog.csdn.net/qq_52301431/article/details/126150723