Vue 项目代理设置的优化

Vue 类的项目开发中项目结构基本都是类似于 Vue-cli 生成的方式,

这种方式开发中,最常用到的模式是开启代理进行 mock 调试或远程调试,

也就是使用了 Vue-cli 设置的配置 proxyTable 或者直接使用 Webpack-dev-server

提供的 proxy 选项。它是采用了 http-proxy 库,所以具体配置可查看:

https://github.com/nodejitsu/node-http-proxy#options

利用配置的这些参数我们可以做更为灵活的配置,达到更好的效果

使用需求

假设我们本地开发目前以下几种状态:

  1. 本地开发,数据使用本地的 mock Server
  2. 涉及权限接口使用本地 mock 数据,其他全部使用指定的一台远程机器
  3. 涉及权限接口使用本地 mock 数据,其他数据分接口使用不同的远程机器
  4. 所有接口使用同一台远程机器

方案

先看下经典的proxyTable 写法:

proxyTable: {
'/authui/': {
target: target,
changeOrigin: true
},
'/vendor/': {
target: target,
changeOrigin: true
}
}

其中用到了 changeOrigin 字段,主要是用于改变请求的 header。细化下需求:

  1. 本地开发:target 指向 localhost 的某个端口即可。至于 host 的验证肯定是不需要的
  2. 部分本地,其他固定的一台远程机器:需要配置 localhost 和远程的地址,远程地址多半是需要验证 host 的
  3. 同二,但机器有多台:需要手动配置多台机器
  4. 同一台远程机器,此时机器可能要严格验证,即 IP 也必须使用域名,配置好系统 host 才可使用

说明:严格验证 host 和普通验证 host 区别主要在于严格验证时,请求的 url 必须是远程机器的域名,

不能直接修改请求的 header 的 host 实现,即必须在系统 host 层面配置好域名。

分析完成具体需求好,就开始准备实现的方式。原有开发方式是执行 npm run dev,如果我们需要在命令行层面添加配置,

就需要设置为 npm run dev --param=paramvalue 的方式。对于使用 npm 的 script 脚本执行的命令,

它参数的获取无法通过 process.env 获得,而且通过 process.env.npm_config_paramName 的方式获取,

使用现成的命令行参数解析库也不是很方便,但为了省事,暂时还是使用 npm 自带的解析。

请求发起过程中需要以下几个参数:

  • host: 发起请求需要指向的 host,可能每台机器验证并不相同
  • port: 代理转发的端口
  • receiver: 用于 push 的远程地址,内包含了 ip 地址,为了省事,没有单独列出 ip 地址

然后定义代理请求自定义类型,用于配置:

  • local: 本地地址,即 localhost
  • remote: 指定的远程机器
  • 其他自定义类型:用于在配置文件中已经指定的其他类型
  • 原版本的请求,如 'http://xxx' 或者 Object 类型的配置,此类代理永不处理

根据需要,我们添加以下几个参数用于控制代理指向地址:

  1. rd: 远程机器的地址
  2. focus: 严格模式,所有自定义类型的代理转换为指定的 rd 机器,只在存在 rd 参数时可用
  3. allLocal:自定义类型代理全部指向本地
  4. host:请求发现是否使用 host,而不是 IP 地址

总结一下(序号指向前面的需求):

  • 需要使用 host 进行访问的情形:4
  • 需要更改 host:除 localhost 外都需要更改
  • 需要对已有类型进行转换:1: 需要将所有自定义类型都转换为 local, 2和3:什么也不转换,4:所有的自定义类型全部转换为 remote 类型

这么一看,貌似 host 是不需要的,它的存在主要是针对某些 机器可能需要使用 host 的方式,所以还是保留一下。

实现

逻辑理清了就很简单了,配置文件设置为:

module.export = {
rd1: {
host: 'dev1.example.com',
port: 8838,
receiver: 'http://1.1.1.1:8888/receiver'
},
rd2: {
host: 'dev2.example.com',
port: 8838,
receiver: 'http://1.1.1.1:8888/receiver'
}
}

proxyTable 配置方式

{
proxyTable: {
'/api1': 'remote',
'/api2': 'rd2',
'/auth/xx': 'local',
'/other': 'http://example.com'
}
}

获取 proxyTable 的代码:

// 处理 proxyTable
const releaseConfig = require('../config/release.conf.js') const rdConfig = releaseConfig[process.env.npm_config_rd]
const isAllRemote = process.env.npm_config_focus
const useHost = isAllRemote || process.env.npm_config_host
// 是否本机开发,本机开发 remote 会指向 local
const isAllLocal = process.env.npm_config_allLocal module.exports = function (proxy) {
const localUrl = `http://localhost:${proxy.localProxyPort}`
const defaultHost = proxy.defaultRdHost || 'dev-example.com'
const localProxyPort = proxy.localProxyPort || 8787 const finalConfig = formatReleaseConfig(releaseConfig)
const remote = finalConfig.remote || {} if (process.env.npm_config_rd) {
if (!rdConfig) {
throw new TypeError('RD 机器名称不存在,请在 config/release.conf.js 中进行配置')
} if (!remote.ip) {
throw new Error('请配置 rd 机器的 receiver')
}
} if (isAllRemote && !rdConfig) {
throw new TypeError('focus 只能在提供了 rd 名称后可设置')
} function formatReleaseConfig (config) {
const result = {}
Object.keys(config).map((key) => {
const value = config[key]
const ipMatch = (value.receiver || '').match(/:\/\/(.*?):\d/)
const ip = ipMatch && ipMatch[1]
result[key] = {
ip,
host: value.host || defaultHost,
port: value.port || '8391'
}
})
// 设置 remote
if (rdConfig) {
const ipMatch = (rdConfig.receiver || '').match(/:\/\/(.*?):\d/)
const ip = ipMatch && ipMatch[1]
result.remote = {
ip,
host: rdConfig.host || defaultHost,
port: rdConfig.port || '8391'
}
}
// 设置 local
result.local = {
ip: 'localhost',
host: 'localhost',
port: localProxyPort
}
return result
} function setProxy (proxyTable) {
const result = {}
Object.keys(proxyTable).forEach((api) => {
let type = proxyTable[api]
const isCustomType = typeof type === 'string' && !/^http/.test(type) if (isCustomType && type !== 'remote' && type !== 'local' && !finalConfig[type]) {
throw new TypeError(`代理类型${type}不正确,请提供 http 或 https 类型的接口,或者指定正确的 release 机器名称`)
} if (type === 'remote' && !finalConfig.remote) {
type = 'local'
}
if (isCustomType) {
if (isAllRemote && type !== 'remote') {
type = 'remote'
}
if (isAllLocal && type !== 'local') {
type = 'local'
}
} const targetConfig = finalConfig[type]
let target = type
if (targetConfig) {
target = {
target: `http://${useHost ? targetConfig.host : targetConfig.ip}:${targetConfig.port}`,
// 使用 host 时需要转换,其他不需要转换
headers: {
host: `${targetConfig.host}:${targetConfig.port}`
}
}
}
result[api] = target
})
return result
} return {
proxyTable: setProxy(proxy.proxyTable),
host: remote.host || defaultHost
}
}

用法

用法中需要配置两种指向:系统 host 和浏览器代理 Host。

之所以要两种 host, 本质上是因为接口使用的域名

和我们的本地访问的域名是相同的,同一域名无法指向两个地址,所以相当于对浏览器端进行了拦截。

系统 host 推荐使用 switchHost 进行切换,浏览器推荐使用 whistle 进行切换。

本地开发

host 配置:无

whistle 配置:默认的域名

127.0.0.1 dev.example.com

启动命令:

npm run dev
npm run dev --allLocal

注: 此时 proxyTable 中配置的 remote 全部转换为 local,在 allLocal 参数时将所有自定义类型转换为 local

本地 + 1 台远程

host 配置:无

whistle 配置:默认的域名

127.0.0.1 dev1.example.com
127.0.0.1 dev2.example.com

启动命令:

npm run dev --rd=rd1
npm run dev --rd=rd1 --host

注: --host 表示使用访问使用 host 而非 ip,使用时需要 host 地址

本地 + n 台远程

host 配置:无

whistle 配置:默认的域名

127.0.0.1 dev1.example.com
127.0.0.1 dev2.example.com

proxyTable 配置:

{
proxyTable: {
'/api1': 'rd1',
'/api2': 'rd2',
'/auth/xx': 'local',
'/other': 'http://example.com'
}
}

启动命令:

npm run dev

远程 1 台机器

host 配置:

1.1.1.1 dev1.example.com
1.1.1.1 dev2.example.com

whistle 配置:默认的域名

127.0.0.1 dev1.example.com
127.0.0.1 dev2.example.com

启动命令:

npm run dev --rd=rd1 --focus

总结

细挖需求,可能还有更简单的方式,在大部分情况下能够减少代码修改,

是 webpack 配置型的实现吧。当然,方式并不完美,尤其在 mac 下,

居然不能支持 --rd xx 这种形式,可以有类似的库吧,后续可以做为深入的内容

Vue 项目代理设置的优化的更多相关文章

  1. Vue首屏性能优化组件

    Vue首屏性能优化组件 简单实现一个Vue首屏性能优化组件,现代化浏览器提供了很多新接口,在不考虑IE兼容性的情况下,这些接口可以很大程度上减少编写代码的工作量以及做一些性能优化方面的事情,当然为了考 ...

  2. PHPSTORM/IntelliJ IDEA 常用 设置配置优化

    PHPSTORM/IntelliJ IDEA 常用 设置配置优化 - meetrice 时间 2014-09-06 10:17:00  博客园-所有随笔区 原文  http://www.cnblogs ...

  3. Hexo + Github 个人博客设置以及优化

    原文地址: Hexo + Github 个人博客设置以及优化 一.博客设置 分类.标签云.关于等页面 在站点目录下分别执行: hexo new page "categories" ...

  4. VUE 2.x SEO 优化问题 vue-meta-info && prerender-spa-plugin 配合使用

    VUE 2.x  SEO  优化问题,以及预渲染问题 1.新建项目可以采用nuxt.js , 配置meta.以及预渲染 都很方便,官网文档都很详细: 2.对于已有项目: vue-meta-info & ...

  5. Linux安全调优1:CentOS防火墙的设置与优化

    CentOS防火墙的设置与优化 时间:2014-09-11 02:11来源:blog.csdn.net 作者:成长的小虫 的BLOG 举报 点击:4908次 一.设置主机防火墙. 开放: 服务器的:w ...

  6. vue+vue-resource设置请求头(带上token)

    前言 有这样的一个需求,后台服务器要求把token放在请求头里面 嗯一般是通过data里面通过参数带过去的 第一种方法 全局改变: Vue.http.headers.common['token'] = ...

  7. vue大型项目高性能优化----想说爱你真的不容易

    一.背景   目前公司的电子合同采用表单设计器+合同业务配合实现,做了半年多后终于上线,但是下边员工普遍反映卡顿,甚至卡死,爆栈.尤其是新增和修改合同页面,因为这部分数据量大,逻辑复杂,很容易崩溃,所 ...

  8. 第3天 IDEA 2021简单设置与优化 Java运算符 包机制

    IDEA 2021简单设置与优化 将工具条显示在上方 View–>Appearance–>Toolbar 鼠标悬停显示 File–>setting–>Editor–>Ge ...

  9. 大型vue单页面项目优化总结

    这是之前在公司oa项目优化时罗列的优化点,基本都已经完成,当时花了点心思整理的,保存在这里,方便以后其他项目用到查漏补缺. 1.打包文件中的app.js文件放入cdn,加快页面首次加载速度 2.提取公 ...

随机推荐

  1. 后端Nodejs利用node-xlsx模块读取excel

    后端Nodejs(利用node-xlsx模块) /** * Created by zh on 16-9-14. */ var xlsx = require("node-xlsx") ...

  2. Oracle的用户,权限以及角色

    一.用户 1.创建用户 创建用户u密码为aa. SQL> create user u identified by aa; 2.为用户赋予权限 这个用户还不能连接数据库,必须为其赋予一些权限才可以 ...

  3. SpringBoot12 QueryDSL01之QueryDSL介绍、springBoot项目中集成QueryDSL

    1 QueryDSL介绍 1.1 背景 QueryDSL的诞生解决了HQL查询类型安全方面的缺陷:HQL查询的扩展需要用字符串拼接的方式进行,这往往会导致代码的阅读困难:通过字符串对域类型和属性的不安 ...

  4. 如何用Word编辑参考文献------这是引用一位大师的

    如何用Word编辑参考文献修改文献是一件非常痛苦的事情,虽然现在也有很多软件可以编排参考文献,其实word本身就可以. 采用合适的编辑方法会方便地做到整齐,规范,自动排序和交叉引用.1.以尾注的方式插 ...

  5. Django学习(六)---博客文章页面的超链接设置

    Django中的超链接 超链接的目标地址 href后面是目标地址 template中可以用 {% url  'app_name : url_name'   param %} app_name:应用命名 ...

  6. 多目标跟踪(MOT)评测标准

    MOT16是多目标跟踪领域非常有名的评测数据集,Ref 1详细阐述了这个数据集的组成以及评测标准(及其评测代码),Ref 2详细地解释了许多标准的由来和考虑,本部分主要介绍MOT任务中常用的评测标准. ...

  7. Linux 终端 Bash 常用快捷键介绍及经验

    1. 最重要的自动补全 命令 解释 Tab 自动补全 不用多说,自动补全可以节省大量时间 2. 编辑跳转 命令 解释 Ctrl + A 跳转到当前行首 Ctrl + E 跳转到当前行末 Alt + F ...

  8. 201621123044《JAVA程序设计》第一周学习总结

    1. 本周学习总结 1.了解了JAVA的诞生以及发展历史简介.JAVA语言的特点,以及JAVA的电脑安装以及环境配置. 2.JAVA不仅可以用eclipse进行编写,也可以在记事本和notepad++ ...

  9. Scrum 冲刺 第三日

    Scrum 冲刺 第三日 目录 要求 项目链接 燃尽图 问题 今日任务 明日计划 成员贡献量 要求 各个成员今日完成的任务(如果完成的任务为开发或测试任务,需给出对应的Github代码签入记录截图:如 ...

  10. Linux安装mongodb总结

    由于自己的博客上线部署时需要用到mongodb来存储图片文件,所以先在本地电脑上安装了mongodb做测试,由于之前没接触过mongodb,所以安装过程中遇到了各种小问题,折腾了好久终于安装好并成功启 ...