egg和vue统一部署到80端口,路由由前端自己渲染;后端

egg和vue 统一部署到80端口,路由由前端自己渲染;后端只提供响应文件和api服务

前言

最近想把egg服务和前端项目部署到同一台服务器上,但是发现有很多问题也查了很多资料,但都没有解决,下面是我遇到的问题和解决办法。

需求:

  1. www.xxx.top域名浏览前端网页
  2. www.api.xxx.top域名调egg服务下的api

问题:

域名默认是80端口,那怎么通过请求www.api.xxx.top访问7001端口呢?直接拼在后面,不那样太low了。我查阅了很多资料后发现可以通过阿里云的隐性url加上中转域名来解决。发现可行就急忙的跑去部署上线了,直接通过www.xxx.top可以访问前端了,但是发现调不了服务打开控制台一看发现了跨域问题。

报错了405发生预检请求。不对啊egg也做了跨域处理设置了白名单和允许的源origin怎么还会出现跨域问题呢,查看请求信息发现远程服务器是阿里的ip。这时候我就想了,怎么是阿里的ip难道是通过阿里服务器转发的请求吗。并且阿里服务器不提供跨域处理所以我的跨域请求没有经过中转域名就被拦了下来导致请求失败没有成功转发到我的服务器。

我的解决方法

  1. 首先把egg后端路由这么定义
    app/router.js
'use strict';

/**
 * @param {Egg.Application} app - egg application
 */
module.exports = app => {
  const { router, controller } = app;
  router.get('/', controller.home.index); // 访问前端项目
  // ...
};

复制代码
  1. 控制器这么定义

app/controller/home.js

'use strict';
const path = require('path')
const fs = require('fs')
const Controller = require('egg').Controller;

class HomeController extends Controller {
  async index() {
    const { ctx } = this;
    ctx.type = 'text/html'
    ctx.body = fs.readFileSync(path.join(__filename,'../../public/index.html'))
  }
}

module.exports = HomeController;

复制代码

如果返回的不是html文件,那应该是被某个中间或插件处理了,解决方法就是把/路由添加到忽略数组中示例如下

// config/config.default.js
config/
 config.auth = {
    ignore: ['/login','/']
  }
复制代码
  1. 前端资源打包路径把默认/修改为/public,执行npm run build打包。其他版本的cli不一样只做参考
// vue.config.js
module.exports = {
   publicPath:'/public'
}
复制代码

这一步的目的就是访问的网页的时候能正常加载js,css等。因为打开网页的后在该路径前拼上域名www.xxx.top/public/js/资源名称对应第4步的配置

  1. 静态资源配置如下
// config/config.default.js
config.static = {
    prefix:'/public/',
    dir:path.join(appInfo.baseDir, 'app/public/')
  };
复制代码
  1. 最后把打包好vue项目往egg目录下的public一丢再把egg部署到80端口下就可以了

image.png

总结

第一次写文章,把最近踩的坑记录一下以防痴呆😊。