背景
如果你的前端应用和后端 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, usecookieDomainRewrite: ""
. - 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, usecookiePathRewrite: ""
. To set path to root usecookiePathRewrite: "/"
. - 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); };