Skip to content

Commit 114e085

Browse files
committed
fix: fix devServer proxy when using object syntax (fix #945)
1 parent 3894308 commit 114e085

File tree

1 file changed

+53
-59
lines changed

1 file changed

+53
-59
lines changed

packages/@vue/cli-service/lib/util/prepareProxy.js

+53-59
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,14 @@ const path = require('path')
1212
const chalk = require('chalk')
1313
const address = require('address')
1414

15+
const defaultConfig = {
16+
logLevel: 'silent',
17+
secure: false,
18+
changeOrigin: true,
19+
ws: true,
20+
xfwd: true
21+
}
22+
1523
module.exports = function prepareProxy (proxy, appPublicFolder) {
1624
// `proxy` lets you specify alternate servers for specific requests.
1725
// It can either be a string or an object conforming to the Webpack dev server proxy configuration
@@ -42,6 +50,47 @@ module.exports = function prepareProxy (proxy, appPublicFolder) {
4250
return !fs.existsSync(maybePublicPath)
4351
}
4452

53+
function createProxyEntry (target, context) {
54+
if (process.platform === 'win32') {
55+
target = resolveLoopback(target)
56+
}
57+
return {
58+
target,
59+
context (pathname, req) {
60+
// not a static request
61+
if (req.method !== 'GET') {
62+
return true
63+
}
64+
// is a static asset
65+
if (!mayProxy(pathname)) {
66+
return false
67+
}
68+
if (context) {
69+
// Explicit context, e.g. /api
70+
return pathname.match(context)
71+
} else {
72+
// Heuristics: if request `accept`s text/html, we pick /index.html.
73+
// Modern browsers include text/html into `accept` header when navigating.
74+
// However API calls like `fetch()` won’t generally accept text/html.
75+
// If this heuristic doesn’t work well for you, use a custom `proxy` object.
76+
return (
77+
req.headers.accept &&
78+
req.headers.accept.indexOf('text/html') === -1
79+
)
80+
}
81+
},
82+
onProxyReq (proxyReq) {
83+
// Browers may send Origin headers even with same-origin
84+
// requests. To prevent CORS issues, we have to change
85+
// the Origin to match the target URL.
86+
if (proxyReq.getHeader('origin')) {
87+
proxyReq.setHeader('origin', target)
88+
}
89+
},
90+
onError: onProxyError(target)
91+
}
92+
}
93+
4594
// Support proxy as a string for those who are using the simple proxy option
4695
if (typeof proxy === 'string') {
4796
if (!/^http(s)?:\/\//.test(proxy)) {
@@ -53,49 +102,13 @@ module.exports = function prepareProxy (proxy, appPublicFolder) {
53102
process.exit(1)
54103
}
55104

56-
let target
57-
if (process.platform === 'win32') {
58-
target = resolveLoopback(proxy)
59-
} else {
60-
target = proxy
61-
}
62105
return [
63-
{
64-
target,
65-
logLevel: 'silent',
66-
// For single page apps, we generally want to fallback to /index.html.
67-
// However we also want to respect `proxy` for API calls.
68-
// So if `proxy` is specified as a string, we need to decide which fallback to use.
69-
// We use a heuristic: if request `accept`s text/html, we pick /index.html.
70-
// Modern browsers include text/html into `accept` header when navigating.
71-
// However API calls like `fetch()` won’t generally accept text/html.
72-
// If this heuristic doesn’t work well for you, use a custom `proxy` object.
73-
context: function (pathname, req) {
74-
return (
75-
mayProxy(pathname) &&
76-
req.headers.accept &&
77-
req.headers.accept.indexOf('text/html') === -1
78-
)
79-
},
80-
onProxyReq: proxyReq => {
81-
// Browers may send Origin headers even with same-origin
82-
// requests. To prevent CORS issues, we have to change
83-
// the Origin to match the target URL.
84-
if (proxyReq.getHeader('origin')) {
85-
proxyReq.setHeader('origin', target)
86-
}
87-
},
88-
onError: onProxyError(target),
89-
secure: false,
90-
changeOrigin: true,
91-
ws: true,
92-
xfwd: true
93-
}
106+
Object.assign({}, defaultConfig, createProxyEntry(proxy))
94107
]
95108
}
96109

97110
// Otherwise, proxy is an object so create an array of proxies to pass to webpackDevServer
98-
return Object.keys(proxy).map(function (context) {
111+
return Object.keys(proxy).map(context => {
99112
if (!proxy[context].hasOwnProperty('target')) {
100113
console.log(
101114
chalk.red(
@@ -105,27 +118,8 @@ module.exports = function prepareProxy (proxy, appPublicFolder) {
105118
)
106119
process.exit(1)
107120
}
108-
let target
109-
if (process.platform === 'win32') {
110-
target = resolveLoopback(proxy[context].target)
111-
} else {
112-
target = proxy[context].target
113-
}
114-
return Object.assign({}, proxy[context], {
115-
context: function (pathname) {
116-
return mayProxy(pathname) && pathname.match(context)
117-
},
118-
onProxyReq: proxyReq => {
119-
// Browers may send Origin headers even with same-origin
120-
// requests. To prevent CORS issues, we have to change
121-
// the Origin to match the target URL.
122-
if (proxyReq.getHeader('origin')) {
123-
proxyReq.setHeader('origin', target)
124-
}
125-
},
126-
target,
127-
onError: onProxyError(target)
128-
})
121+
const entry = createProxyEntry(proxy[context].target, context)
122+
return Object.assign({}, defaultConfig, proxy[context], entry)
129123
})
130124
}
131125

0 commit comments

Comments
 (0)