路由&跨域&CURL 
路由 
基础版 
路由定义了 请求路径(URL) 和 控制器(Controller) 之间的映射关系,即用户访问的网址应交由哪个控制器进行处理。我们打开 app/router.js 看一下:
js
module.exports = (app) => {
  const { router, controller } = app;
  router.get("/", controller.home.index);
};- 路由定义 
- 找到 router.js 在里面写对应的路由信息 比如
js
module.exports = (app) => {
  const { router, controller } = app;
  router.get("/login", controller.get.login.index);
};- 这句代码的意思是:
bash
用户用get方法访问路径是login的时候,由controller下面的get文件夹下面的login.js文件下面的index这个方法来处理- 动词介绍 
可以看到,路由文件导出了一个函数,接收 app 对象作为参数,通过下面的语法定义映射关系:
js
router.verb("path-match", controllerAction);其中verb一般是 http 动词的小写,举例
| 动词 | 名称 | 
|---|---|
| HEAD | router.head | 
| OPTIONS | router.options | 
| GET | router.get | 
| PUT | router.put | 
| POST | router.post | 
| PATCH | router.patch | 
| DELETE | router.delete 或 router.del | 
除此之外,还有一个特殊的动词 router.redirect 表示重定向。
- 函数匹配 
而 controllerAction 则是通过点(·)语法指定 controller 目录下某个文件内的某个具体函数,例如:
bash
controller.home.index // 映射到 controller/home.js 文件的 index 方法
controller.v1.user.create // controller/v1/user.js 文件的 create 方法- 其他 
- RestFul 风格
Egg Router 支持以 Restful 风格定义路由,例如:
js
router.resources("posts", "/posts", controller.posts);上述代码定义了以下映射关系:
- GET /posts -> controller.posts.index
- GET /posts/new -> controller.posts.new
- GET /posts/:id -> controller.posts.show
- GET /posts/:id/edit -> controller.posts.edit
- POST /posts -> controller.posts.create
- PATCH /posts/:id -> controller.posts.update
- PUT /posts/:id -> controller.posts.update
- DELETE /posts/:id -> controller.posts.destroy
只需要到controller中实现对应的方法即可
- 路由重定向
js
router.redirect("/home", "/");插件版 egg-router-plus 
这个插件好处就 2 点 1.自动导入 router 文件夹下面的文件夹(仅一层)下面的 js 文件 2.支持 namespace 命名空间
- 安装 
bash
npm install egg-router-plus --save- 配置 
在 config/plugin.js 中启用插件:
js
exports.routerPlus = {
  enable: true,
  package: "egg-router-plus",
};- 使用 
特别注意 controller 下面的文件夹名字和路由名必须小写,注意:prefix 和 path 不能是正则表达式,prefix 不能是 /。
- (1) 在 app 目录下新建一个 router 文件夹
在这个文件夹下面新建一个 xxx.js 文件(你自己定义的路由文件)
- (2) 在 xxx.js 里面写路由信息
js
module.exports = (app) => {
  const { router, controller } = app;
  // router
  const subRouter = router.namespace("/login");
  subRouter.get("/:id", controller.login.loginapi.index);
  // 这个结果就是 /login/:id ,调用controller/login文件夹下面的loginapi.js文件下面的index方法
};- (3) 在控制器里面实现对应的方法
js
const { Controller } = require("egg");
class LoginController extends Controller {
  async index() {
    const { ctx } = this;
    const result = ctx.params.id;
    ctx.body = `测试登陆有没有${result}`;
  }
}
module.exports = LoginController;- 使用中间件(后续会说) 
bash
router.verb('path-match', app.controller.action);
router.verb('path-match', middleware1, ..., middlewareN, app.controller.action);
router.verb('router-name', 'path-match', app.controller.action);
router.verb('router-name', 'path-match', middleware1, ..., middlewareN, app.controller.action);路由参数 
GET 有两种方式 
- 第一种 自由模式 通过?例如:?id=3&name=xxx通过ctx.query获取
js
  // 自由传参模式 通过?
  async getquery() {
    const { ctx } = this;
    const result = JSON.stringify(ctx.query);
    ctx.body = `<h1>getquery: ${result}</h1>`;
  }- 第二种 严格模式 通过路径 例如 /:name/:id通过ctx.params获取
/:name/:id? 表示 id 可以传或者不传,这里的?只能放到结尾
js
  async getyangequery() {
    const { ctx } = this;
    const result = JSON.stringify(ctx.params);
    ctx.body = `<h1>getquery: ${result}</h1>`;
  }POST 
- 通过ctx.request.body获取
js
  async postquery() {
    const { ctx } = this;
    const result = JSON.stringify(ctx.request.body);
    ctx.body = `<h1>postquery: ${result}</h1>`;
  }跨域 
安装 
bash
npm i egg-cors --save配置插件 
- {app_root}/config/plugin.js
js
exports.cors = {
  enable: true,
  package: "egg-cors",
};配置 
- config / config.default.js 目录下配置
js
config.security = {
  // 关闭 csrf
  csrf: {
    enable: false,
  },
  // 跨域白名单
  domainWhiteList: ["http://localhost:3000"],
};
// 允许跨域的方法
config.cors = {
  origin: "*",
  allowMethods: "GET, PUT, POST, DELETE, PATCH",
  // cookie跨域配置
  credentials: true,
};CURL 
有的时候服务器也需要给别的服务器发送请求,这个时候就需要用到 curl
创建对应的路由和 控制器 
- 路由(新建 httpclient.js)
js
module.exports = (app) => {
  const { router, controller } = app;
  // router
  const HttpRouter = router.namespace("/httpclient");
  HttpRouter.get("/get", controller.httpclient.httpclient.get);
  HttpRouter.post("/post", controller.httpclient.httpclient.post);
};控制器里面使用 curl 
js
"use strict";
const Controller = require("egg").Controller;
class HttpClientController extends Controller {
  async get() {
    const { ctx } = this;
    // 示例:请求一个 npm 模块信息
    const result = await ctx.curl("https://httpbin.org/get?foo=bar", {
      // 自动解析 JSON 响应
      dataType: "json",
      // 3 秒超时
      timeout: 3000,
      //头部
      headers: {},
    });
    ctx.body = result.data; // 响应结果
  }
  async post() {
    const { ctx } = this;
    const result = await ctx.curl("https://httpbin.org/post", {
      // 必须指定 method
      method: "POST",
      // 通过 contentType 告诉 HttpClient 以 JSON 格式发送
      contentType: "json",
      data: {
        hello: "world",
        now: Date.now(),
      },
      // 明确告诉 HttpClient 以 JSON 格式处理返回的响应 body
      dataType: "json",
      headers: {},
    });
    ctx.body = result.data;
  }
}
module.exports = HttpClientController;