Vue CLI 中的 vue.config.js devServer.proxy 配置的一般技巧

背景

如果你的前端应用和后端 API 服务器没有运行在同一个主机上,你需要在开发环境下将 API 请求代理到 API 服务器。这个问题可以通过 vue.config.js 中的 devServer.proxy 选项来配置。

使用方式

devServer.proxy 可以是一个指向开发环境 API 服务器的字符串:


module.exports = {
  devServer: {
    proxy: 'http://localhost:4000'
  }
}

这会告诉开发服务器将任何未知请求 (没有匹配到静态文件的请求) 代理到 http://localhost:4000。

普通的代理控制行为


module.exports = {
  devServer: {
    proxy: {
      '/api': {
        target: '',
        ws: true,
        changeOrigin: true
      },
      '/foo': {
        target: ''
      }
    }
  }
}

高级的代理控制行为


const port = process.env.port || process.env.npm_config_port || 9528 // dev port
module.exports = {
    port: port,
    open: true,
    overlay: {
      warnings: false,
      errors: true
    },
    proxy: {
      // detail: https://cli.vuejs.org/config/#devserver-proxy
      '/dev-api': {
        target: `http://www.xxx.com`,
        changeOrigin: true,
        pathRewrite: {
          '^/dev-api': '' // 思路是如果是开发环境,就给所有要代理的接口统一加上前缀,然后代理请求时再统一通过rewrite去掉
        }
      }
    }
}

http-proxy 可配置选项(http-proxy options )

下面配置的选项是由 http-proxy 库提供的。在 Vue 项目中可能用上,需要着重关注的下面用【】标注。

  • 【option.target】: 【需要被代理目标 url】url string to be parsed with the url module
  • option.forward: url string to be parsed with the url module
  • option.agent: object to be passed to http(s).request (see Node’s https agent and http agent objects)
  • option.ssl: object to be passed to https.createServer()
  • option.ws: true/false: if you want to proxy websockets
  • option.xfwd: true/false, adds x-forward headers
  • 【option.secure】: 【有时需要对 https + IP 的 URL 进行代理时,需设为 true, 不然可能会报 ERR_TLS_CERT_ALTNAME_INVALID 错误】 true/false, if you want to verify the SSL Certs
  • option.toProxy: true/false, passes the absolute URL as the path (useful for proxying to proxies)
  • option.prependPath: true/false, Default: true – specify whether you want to prepend the target’s path to the proxy path
  • option.ignorePath: true/false, Default: false – specify whether you want to ignore the proxy path of the incoming request (note: you will have to append / manually if required).
  • option.localAddress : Local interface string to bind for outgoing connections
  • 【option.changeOrigin】: 【改为同域,一般要加并设为 true】 true/false, Default: false – changes the origin of the host header to the target URL
  • option.preserveHeaderKeyCase: true/false, Default: false – specify whether you want to keep letter case of response header key
  • option.auth : Basic authentication i.e. ‘user:password’ to compute an Authorization header.
  • option.hostRewrite: rewrites the location hostname on (301/302/307/308) redirects.
  • option.autoRewrite: rewrites the location host/port on (301/302/307/308) redirects based on requested host/port. Default: false.
  • option.protocolRewrite: rewrites the location protocol on (301/302/307/308) redirects to ‘http’ or ‘https’. Default: null.
  • option.cookieDomainRewrite: rewrites domain of set-cookie headers. Possible values:
    • false (default): disable cookie rewriting
    • String: new domain, for example cookieDomainRewrite: "new.domain". To remove the domain, use cookieDomainRewrite: "".
    • Object: mapping of domains to new domains, use "*" to match all domains.
      For example keep one domain unchanged, rewrite one domain and remove other domains:

      
      cookieDomainRewrite: {
        "unchanged.domain": "unchanged.domain",
        "old.domain": "new.domain",
        "*": ""
      }
      
  • option.cookiePathRewrite: rewrites path of set-cookie headers. Possible values:
    • false (default): disable cookie rewriting
    • String: new path, for example cookiePathRewrite: "/newPath/". To remove the path, use cookiePathRewrite: "". To set path to root use cookiePathRewrite: "/".
    • Object: mapping of domains to new domains, use "*" to match all domains. For example, to keep one path unchanged, rewrite one path and remove other paths:
      
      cookiePathRewrite: {
        "/unchanged.path/": "/unchanged.path/",
        "/old.path/": "/new.path/",
        "*": ""
      }
      
  • option.headers: object, adds request headers. (Example: {host:’www.example.org’})
  • option.proxyTimeout: timeout (in millis) when proxy receives no response from target
  • option.timeout: timeout (in millis) for incoming requests
  • option.followRedirects: true/false, Default: false – specify whether you want to follow redirects
  • option.selfHandleResponse true/false, if set to true, none of the webOutgoing passes are called and it’s your responsibility to appropriately return the response by listening and acting on the proxyRes event
  • option.buffer: stream of data to send as the request body. Maybe you have some middleware that consumes the request stream before proxying it on e.g. If you read the body of a request into a field called ‘req.rawbody’ you could restream this field in the buffer option:
    
    'use strict';
    
    const streamify = require('stream-array');
    const HttpProxy = require('http-proxy');
    const proxy = new HttpProxy();
    
    module.exports = (req, res, next) => {
    
      proxy.web(req, res, {
        target: 'http://localhost:4003/',
        buffer: streamify(req.rawBody)
      }, next);
    
    };