@@ -12,6 +12,14 @@ const path = require('path')
1212const chalk = require ( 'chalk' )
1313const address = require ( 'address' )
1414
15+ const defaultConfig = {
16+ logLevel : 'silent' ,
17+ secure : false ,
18+ changeOrigin : true ,
19+ ws : true ,
20+ xfwd : true
21+ }
22+
1523module . 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 ( ! / ^ h t t p ( 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