From 25f81f2bea6fd1553425bc8fe10b4a6aa16a58f2 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Mon, 22 May 2017 17:04:17 +0100 Subject: [PATCH] Files in public/ folder should not be requested through proxy (#2326) --- packages/react-dev-utils/README.md | 2 +- .../react-dev-utils/WebpackDevServerUtils.js | 20 +++++++++---------- packages/react-scripts/scripts/start.js | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/react-dev-utils/README.md b/packages/react-dev-utils/README.md index 5daa9f062b8..166e1bfaea3 100644 --- a/packages/react-dev-utils/README.md +++ b/packages/react-dev-utils/README.md @@ -283,7 +283,7 @@ Returns a Promise resolving to either `defaultPort` or next available port if th Creates a Webpack compiler instance for WebpackDevServer with built-in helpful messages. Takes the `require('webpack')` entry point as the first argument. To provide the `urls` argument, use `prepareUrls()` described below. -##### `prepareProxy(proxySetting: string): Object` +##### `prepareProxy(proxySetting: string, appPublicFolder: string): Object` Creates a WebpackDevServer `proxy` configuration object from the `proxy` setting in `package.json`. diff --git a/packages/react-dev-utils/WebpackDevServerUtils.js b/packages/react-dev-utils/WebpackDevServerUtils.js index 02ce10f3e9b..70b5e6a7eab 100644 --- a/packages/react-dev-utils/WebpackDevServerUtils.js +++ b/packages/react-dev-utils/WebpackDevServerUtils.js @@ -9,6 +9,8 @@ 'use strict'; const address = require('address'); +const fs = require('fs'); +const path = require('path'); const url = require('url'); const chalk = require('chalk'); const detect = require('@timer/detect-port'); @@ -240,7 +242,7 @@ function onProxyError(proxy) { }; } -function prepareProxy(proxy) { +function prepareProxy(proxy, appPublicFolder) { // `proxy` lets you specify alternate servers for specific requests. // It can either be a string or an object conforming to the Webpack dev server proxy configuration // https://webpack.github.io/docs/webpack-dev-server.html @@ -264,13 +266,11 @@ function prepareProxy(proxy) { process.exit(1); } - // Otherwise, if proxy is specified, we will let it handle any request. - // There are a few exceptions which we won't send to the proxy: - // - /index.html (served as HTML5 history API fallback) - // - /*.hot-update.json (WebpackDevServer uses this too for hot reloading) - // - /sockjs-node/* (WebpackDevServer uses this for hot reloading) - // Tip: use https://jex.im/regulex/ to visualize the regex - const mayProxy = /^(?!\/(index\.html$|.*\.hot-update\.json$|sockjs-node\/)).*$/; + // Otherwise, if proxy is specified, we will let it handle any request except for files in the public folder. + function mayProxy(pathname) { + const maybePublicPath = path.resolve(appPublicFolder, pathname.slice(1)); + return !fs.existsSync(maybePublicPath); + } // Support proxy as a string for those who are using the simple proxy option if (typeof proxy === 'string') { @@ -301,7 +301,7 @@ function prepareProxy(proxy) { // However API calls like `fetch()` won’t generally accept text/html. // If this heuristic doesn’t work well for you, use a custom `proxy` object. context: function(pathname, req) { - return mayProxy.test(pathname) && + return mayProxy(pathname) && req.headers.accept && req.headers.accept.indexOf('text/html') === -1; }, @@ -341,7 +341,7 @@ function prepareProxy(proxy) { } return Object.assign({}, proxy[context], { context: function(pathname) { - return mayProxy.test(pathname) && pathname.match(context); + return mayProxy(pathname) && pathname.match(context); }, onProxyReq: proxyReq => { // Browers may send Origin headers even with same-origin diff --git a/packages/react-scripts/scripts/start.js b/packages/react-scripts/scripts/start.js index 92d4f562fdd..a451228df8b 100644 --- a/packages/react-scripts/scripts/start.js +++ b/packages/react-scripts/scripts/start.js @@ -66,7 +66,7 @@ choosePort(HOST, DEFAULT_PORT) const compiler = createCompiler(webpack, config, appName, urls, useYarn); // Load proxy config const proxySetting = require(paths.appPackageJson).proxy; - const proxyConfig = prepareProxy(proxySetting); + const proxyConfig = prepareProxy(proxySetting, paths.appPublic); // Serve webpack assets generated by the compiler over a web sever. const serverConfig = createDevServerConfig( proxyConfig,