Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

devServer proxy not working #793

Closed
gjunkie opened this issue Feb 17, 2017 · 49 comments
Closed

devServer proxy not working #793

gjunkie opened this issue Feb 17, 2017 · 49 comments

Comments

@gjunkie
Copy link

gjunkie commented Feb 17, 2017

Do you want to request a feature or report a bug?
Bug

What is the current behavior?
devServer proxy doesn't proxy.

If the current behavior is a bug, please provide the steps to reproduce.
Client server running at localhost:8080 and API server running at localhost:8000. I've tried several variations of what to proxy (api/*, /api/**, api/**, etc). Use the following proxy settings:

  devServer: {
    hot: true,
    contentBase: resolve(__dirname, 'dist'),
    publicPath: '/',
    proxy: {
      '/api/**': {
        target: 'http://localhost:8000',
        secure: false,
        changeOrigin: true,
      }
    },
  },

What is the expected behavior?
Hitting /api/path should be proxied to http://localhost:8000/api/path but is instead hitting http://localhost:8080/api/path.

Please mention your webpack and Operating System version.

  • webpack @ 2.2.1
  • webpack-dev-server @ 2.3.0
  • macOS 10.12.3
@steve-taylor
Copy link

steve-taylor commented Feb 17, 2017

Have you tried '/api'?

@gjunkie
Copy link
Author

gjunkie commented Feb 17, 2017

@steve-taylor I have indeed. /api, api, /api/path, etc. Every variation I could think of.

@SpaceK33z
Copy link
Member

SpaceK33z commented Feb 17, 2017

I tried to reproduce this, but it does work for me. What's interesting though is that the error message I get in the browser is wrong. It says "Error occured while trying to proxy to: localhost:8080/api/users" even though the proxy is set to http://localhost:8000. When I start a server on port 8000 however, it does work correctly.

@steve-taylor
Copy link

steve-taylor commented Feb 17, 2017

I wonder if there's a way to plug in a reverse proxy that actually works, rather than being handcuffed to http-proxy-middleware.

@gjunkie
Copy link
Author

gjunkie commented Feb 17, 2017

Yeah not sure.. Here's my whole config in case there's something else afoot. Maybe I've got something funky in the entry?

const { resolve } = require('path');
const webpack = require('webpack');

module.exports = {
  entry: [
    'react-hot-loader/patch',
    'webpack-dev-server/client?http://localhost:8080',
    'webpack/hot/only-dev-server',
    './app.js',
  ],

  output: {
    filename: 'bundle.js',
    path: resolve(__dirname, 'dist'),
    publicPath: '/',
  },

  context: resolve(__dirname, 'client'),

  devtool: 'inline-source-map',

  devServer: {
    hot: true,
    contentBase: resolve(__dirname, 'dist'),
    publicPath: '/',
    proxy: {
      '/api/**': {
        target: 'http://localhost:8000',
        secure: false,
        changeOrigin: true,
      }
    },
  },

  module: {
    rules: [
      {
        test: /\.js$/,
        use: [
          'babel-loader',
        ],
        exclude: /node_modules/
      },
      {
        test: /\.css$/,
        use: [
          'style-loader',
          'css-loader?modules',
          'postcss-loader',
        ],
      },
    ],
  },

  plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NamedModulesPlugin()
  ],
};

@SpaceK33z
Copy link
Member

@steve-taylor what specific issues are you having? I would suggest creating github issues on http-proxy-middleware for those. The author of http-proxy-middleware is very responsive and helpful.

@SpaceK33z
Copy link
Member

@gjunkie can you make a repository with a minimal version of the backend you have on port 8000? That's the only way to be able to debug this further down.

@gjunkie
Copy link
Author

gjunkie commented Feb 21, 2017

@SpaceK33z I decided to shift over to use Hapijs' cors feature for my needs, however this is the repo I was attempting to proxy in. Beyond removing the proxy option, there haven't been other changes, in case this helps.

https://github.com/gjunkie/hapi-react-kit

@nancruz
Copy link

nancruz commented Mar 31, 2017

I have the same problem as @gjunkie. Starting from v1.15.0 the http-proxy-middleware is installed as dependency and a ECONNRESET error is thrown each time I try to make a request to the backend.

Apparently, it is only happening in OS X environment because my colleagues at work are using Ubuntu and they can't reproduce this problem.

@rpdmiranda
Copy link

I could reproduce this bug on OS X. In Windows, it is working just fine.

@Cottin
Copy link

Cottin commented Apr 21, 2017

I couldn't get devServer proxy to work either (OS X 10).
I'm running with a server.js which reads webpack.config.js and my workaround was a reverse proxy using http-proxy in server.js:

var httpProxy = require('http-proxy');
var apiProxy = httpProxy.createProxyServer();

// ... was here before
var app = express();
var compiler = webpack(config);

app.use(require('webpack-dev-middleware')(compiler, {
  publicPath: config.output.publicPath
}));

app.use(require('webpack-hot-middleware')(compiler));
// ... end of was here before

app.all("/api/*", function(req, res) {
    apiProxy.web(req, res, {target: 'http://localhost:3102'});
});

Reference: https://codeforgeek.com/2015/12/reverse-proxy-using-expressjs/

@guoxiangwen
Copy link

How to set proxy buffer, i want to upload some files to backend

@r01010010
Copy link

Having the same issue here, also OSX

@yuduxyz
Copy link

yuduxyz commented May 22, 2017

same issue on OSX

@maxsitu
Copy link

maxsitu commented Jun 1, 2017

Same issue on OSX as well.

@r01010010
Copy link

r01010010 commented Jun 1, 2017

This configuration is working for me on OSX (I sweated blood to make it work). I have the GNU Coreutils installed, by the way (don't know if has something to do).

, proxy: [
          {
            path: /^\/styleguide(?!\/core-css\/build)/
          , target: 'http://localhost:8000'
          , bypass: function(req, res, _options) {
              return req.url.replace('styleguide', styleguideRoothPath + '/build');
            }
          }
        , {
            path: "**",
            target: "http://localhost:3000",
            secure: false,
            bypass: function(req, res, options) {
              if(req.url === '' || req.url === '/') {
                res.statusCode = 302;
                res.setHeader('Location', '/a/');
                return '/a/';
              }

              var frontend = new RegExp("^\/$^|\/a\/index\.html|^\/a\/|^\/a$|^\/styleguide");
              if (frontend.test(req.url)) return req.url;
            }
          }
        ]

@ghost
Copy link

ghost commented Jul 19, 2017

Same issue on OSX.

@jellyfish-tom
Copy link

jellyfish-tom commented Jul 20, 2017

replace localhost with [::1].
like so: 'http://[::1]:3000'

this works for me:

devServer: {
  proxy: {
    "*": "http://[::1]:8081"
    // "secure": false,
    // "changeOrigin": true
  }
},

one wildcard, or double, with 'secure' or 'changeOrigin' - doesnt matter. [::1] is the game changer.
Good luck!

@sun-slaven
Copy link

Meet the same issue on mac, any progress here?

@shellscape
Copy link
Contributor

We've got a few workarounds posted for folks running into the issue. It seems that this might be slightly edge casey, however. If anyone would like to put together a Pull Request, we'd happily review it and revisit this issue.

@italoborges
Copy link

italoborges commented Aug 14, 2017

In my case, I had to rewrite the path:

proxy: {
   '/api/**': {
      target: 'http://localhost:9596/',
      pathRewrite: { '^/api': '' },
      secure: false,
      logLevel: 'debug'
   }
}

Hope this can help.

@erosenberg
Copy link

erosenberg commented Aug 25, 2017

I'm still having issues with this on Mac OSX and have tried everything above.
What else can I do to troubleshoot?

Related: #458 (comment)

EDIT: I think I was expecting the opposite behavior for some weird reason. By proxying the web server through the dev server, I should still be using the dev server, not the actual server while developing.

@bdoooh
Copy link

bdoooh commented Aug 31, 2017

It's working for me now. Turned out I was just missing adding new webpack.HotModuleReplacementPlugin(), to the plugins array

@jrweinb
Copy link

jrweinb commented Sep 13, 2017

Make sure that your request url and port matches that which your webpack-dev-server is running on. So, if your api is located at http://localhost:5000, and your dev server is running on http://localhost:8080, make sure all of your requests are to http://localhost:8080. Its best to make your requests to localhost:8080/api (to avoid conflict with app routes) and use the path rewrite to remove the /api.

Example:
Webpack devserver proxy config:

proxy: {
    '/api': {
        target: 'http://localhost:5000',
        pathRewrite: { '^/api': '' },
    },
}

Webpack dev server running on: http://localhost:8080
Desired API endpoint: http://localhost:5000/items

In your app, make the request to: http://localhost:8080/api/items.

This should work. It seems to me that all of the above issues stem from making the request to the API url and port rather than the webpack dev server url and port and using the proxy and path rewrite to direct the request to the API.

@withintheruins14
Copy link

withintheruins14 commented Oct 1, 2017

@jrweinb, thanks for your clear explanation. I was trying to GET the API port like you had described, but it is still not working. In the console I have two errors,

GET http://localhost:8080/api/prospects 404 (NOT FOUND)
Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0

The second error points to line 4 here, there is no '<' as described

export function fetchProspects() {
  return (dispatch) => {
    dispatch(requestProspects());
    return fetch('http://localhost:8080/api/prospects')
      .then(response => response.json())
      .then(json => dispatch(receiveProspects(json)));
  };
}

@jrweinb
Copy link

jrweinb commented Oct 2, 2017

@withintheruins14 - (I deleted a previous reply as it was wrong). It looks like your API is not working. The 404 html is getting parsed in response => response.json()

@withintheruins14
Copy link

withintheruins14 commented Oct 5, 2017

** SOLVED **

@jrweinb, thanks for sticking with me - I am still trying to get this sorted. Yes, my request was 404ing but that is because the dev-server proxy isn't working. To me, my files appear in proper order, here they are:

actions/prospect.js

export function fetchProspects() {
  return (dispatch) => {
    dispatch(requestProspects());
    return fetch('http://localhost:8080/api/prospects')
      .then(response => response.json())
      .then(json => dispatch(receiveProspects(json.data)))
      .catch(ex => dispatch(requestProspectsFailure(ex)));
  };
}

webpack.config.js

const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const DIST_DIR = path.resolve(__dirname, "dist");
const SRC_DIR = path.resolve(__dirname, "src");

const config = {
  entry: [
    "babel-polyfill",
    SRC_DIR + "/app/index.js",
    SRC_DIR + "/app/assets/stylesheets/application.scss",
    "font-awesome/scss/font-awesome.scss",
  ],
  output: {
    path: DIST_DIR + "/app/",
    filename: "bundle.js",
    publicPath: "/app/"
  },
  devtool: 'inline-source-map',
  devServer: {
    contentBase: './dist',
    historyApiFallback: true,
    proxy: {
    '/api': {
        target: 'http://localhost:5001',
    },
}
  },
  module: {
    rules: [
      {
        enforce: "pre",
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "eslint-loader",
        options: {
          failOnWarning: false,
          failOnError: true
        }
      },
      {
        test: /\.js$/,
        include: SRC_DIR,
        loader: 'babel-loader',
        query: {
          presets: ['react', 'stage-2']
        }
      },
      {
        test: /\.css$/,
        use: ExtractTextPlugin.extract({
          use: 'css-loader?importLoaders=1'
        })
      },
      {
        test: /\.scss$/,
        use: ExtractTextPlugin.extract(['css-loader', 'sass-loader'])
      },
      {
        test: /\.(jpe?g|png|gif|svg)$/i,
        loaders: ['file-loader?context=src/images&name=images/[path][name].[ext]', {
          loader: 'image-webpack-loader',
          query: {
            mozjpeg: {
              progressive: true,
            },
            gifsicle: {
              interlaced: false,
            },
            optipng: {
              optimizationLevel: 7,
            },
            pngquant: {
              quality: '75-90',
              speed: 3,
            },
          },
        }],
        exclude: /node_modules/,
        include: __dirname,
      },
      {
        test: /\.woff2?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
        // loader: "url?limit=10000"
        use: "url-loader"
      },
      {
        test: /\.(ttf|eot|svg)(\?[\s\S]+)?$/,
        use: 'file-loader'
      },
    ]
  },
  plugins: [
    new ExtractTextPlugin({
      filename: "application.css",
      allChunks: true
    })
  ]
};

module.exports = config;

package.json

"scripts": {
    "test": "jest",
    "watch": "webpack --progress --watch",
    "start": "npm run build",
    "build": "webpack -d && cp src/index.html dist/index.html && webpack-dev-server --inline --hot --history-api-fallback",
    "build:prod": "webpack -p && cp src/index.html dist/index.html"
  }

Thanks!

@withintheruins14
Copy link

The above was solved. My problem was on the server and not within my webpack.config.js. Our Flask server prevents all requests from different servers when a server name is specified. To fix this, we simply left the server name unspecified in config.py. Thanks for your help @jrweinb

@wasserholz
Copy link

@jellyfish-tom your solution did it for me with Mac OSX 10

replace localhost with [::1].
like so: 'http://[::1]:3000'

this works for me:

devServer: {
  proxy: {
    "*": "http://[::1]:8081"
    // "secure": false,
    // "changeOrigin": true
  }
},

@mzvast
Copy link

mzvast commented Mar 7, 2018

@italoborges You saved my life:)

pathRewrite: {'^/api': ''}

@michaeljaekel
Copy link

I ran into the same issue and found

new CopyWebpackPlugin([
      {
        from: path.resolve(__dirname, '../static'),
        to: config.dev.assetsSubDirectory,
        ignore: ['.*']
      }
    ])

in webpack.dev.conf.js .
Seems, it changes the way, proxyTable is handling the path to static??
I commented it out, restarted npm run dev and all is running fine again.
Is there a better way to handle this than deleting the plugin?

BTW. This is my config for proxytable (now working again):

proxyTable: {
			'/static': {
				target: 'http://firedev.local:8888',
				changeOrigin: true,
				logLevel: 'debug'
			}
		},

@sarahmarciano
Copy link

I am also facing this issue
I am trying to be solving it till this morning but with no success
I've tried every solution but nothing is working for me
can anyone help please?

@Rikkihon
Copy link

I'm having a similar problem with the proxy - but same here, nothin is workin. I have a repo I could share: https://github.com/writesandy/SSMRB

@HabelJustin
Copy link

HabelJustin commented Aug 19, 2018

@jellyfish-tom thanks

Now mine is working, here's my config:

devServer: {
historyApiFallback: true,
contentBase: './dist',
watchOptions: {
aggregateTimeout: 500,
poll: 1000,
ignored: /node_modules/
},
proxy: { '/api': { target: 'http://[::1]:3030', secure: false } }
}

@italoborges
Copy link

italoborges commented Dec 3, 2018

For Webpack 4 and OSX10, I had to add changeOrigin property to make it work.

{
    historyApiFallback: true,
    contentBase: './static',
    port: 9095,
    proxy: {
        '/api/**': {
            target: 'http://another-url',
            pathRewrite: {
                '^/api': '',
            },
            secure: false,
            changeOrigin: true,
            logLevel: 'debug',
        },
    },
};

@SilentGert
Copy link

For us setting the header Connection: keep-alive did the trick. Requests were handled by the backend server and a response was sent as well, nevertheless we saw the error ECONNRESET for some of the API requests before.

'api' : {
  target: SERVER_URL,
  secure: false,
  changeOrigin: true,
  headers: {
    Connection: 'keep-alive',
  },
}

@barrywilks7
Copy link

Our UX guy has also been suffering the ECONNRESET on macOS for some time and he's tried most things to solve it, however the solution from @SilentGert has solved the problem.

@onx2
Copy link

onx2 commented Jun 14, 2019

If this is helpful for any one browsing the topic, this setup works for me on webpack 4.33.0 and webpack-dev-server 3.7.1.

module.exports = {
  entry: [
    'webpack-dev-server/client?http://localhost:8080',
    'webpack/hot/dev-server',
    './src/index.tsx'
  ],
  devtool: 'source-map',
  devServer: {
    contentBase: path.resolve(__dirname, 'dist'),
    hotOnly: true,
    progress: true,
    port: 8080,
    proxy: {
      '/api': 'http://localhost:4000',
    },
    open: true,
    watchContentBase: true,
    inline: true,
    historyApiFallback: true,
    stats: 'minimal'
  },
...
}

I'm using osX and these dependencies (if you find it relevant to your setup):

"devDependencies": {
    "@types/react": "^16.8.19",
    "@types/react-dom": "^16.8.4",
    "@types/react-router-dom": "^4.3.3",
    "@types/webpack-env": "^1.13.9",
    "html-webpack-plugin": "^3.2.0",
    "ts-loader": "^6.0.2",
    "typescript": "^3.5.1",
    "webpack": "^4.33.0",
    "webpack-bundle-analyzer": "^3.3.2",
    "webpack-cli": "^3.3.4",
    "webpack-dev-server": "^3.7.1"
  },
  "dependencies": {
    "react": "^16.8.6",
    "react-dom": "^16.8.6",
    "react-router-dom": "^5.0.1"
  }

I also noticed that using the proxy option with historyApiFallback prevents the latter from working (500 Internal Server Error)... An issue for another day I suppose.

@ValeriaGrabnitskaya
Copy link

@jrweinb thank you! it works!

@yarosdev
Copy link

proxy to http://some.localhost:8888 not working! Just ENOTFOUND

@imzubair10
Copy link

This should work:

devServer: {
    contentBase: path.join(__dirname, "/dist"),
    historyApiFallback: true,
    publicPath: '/',
    inline: true,
    port: 8080,
    stats: { colors: true },
    hot: true,
    proxy: {
      '/api/**': {
        target: 'http://localhost:44310',
        pathRewrite: { '^/api': '' },
        secure: false,
        changeOrigin: true
      }
    }
}

@RK-developer
Copy link

replace localhost with [::1].
like so: 'http://[::1]:3000'

this works for me:

devServer: {
  proxy: {
    "*": "http://[::1]:8081"
    // "secure": false,
    // "changeOrigin": true
  }
},

one wildcard, or double, with 'secure' or 'changeOrigin' - doesnt matter. [::1] is the game changer.
Good luck!

I have tried, but getting this issue
Error occurred while trying to proxy request /api/v3/sign-in from localhost:9898 to http://[::1]:8081 (ECONNREFUSED) (https://nodejs.org/api/errors.html#errors_common_system_errors)

@RK-developer
Copy link

RK-developer commented May 2, 2020

This should work:

devServer: {
    contentBase: path.join(__dirname, "/dist"),
    historyApiFallback: true,
    publicPath: '/',
    inline: true,
    port: 8080,
    stats: { colors: true },
    hot: true,
    proxy: {
      '/api/**': {
        target: 'http://localhost:44310',
        pathRewrite: { '^/api': '' },
        secure: false,
        changeOrigin: true
      }
    }
}

getting error "http://localhost:9898/api/v3/sign-in 404 (Not Found)"
till it using vue url (localhost:9898), its not proxy the given url(localhost:3337) for api request
vue js port : 9898
backend api port: 3337

@james-bright-ca
Copy link

In my case it doesn't work when a file that should be proxied exists.
For example, request to /api/auth.php
/public/api/auth.php - Will not work if the file above exists

tetchel added a commit to tetchel/argo-cd that referenced this issue Oct 8, 2020
Switching the hostname from 'localhost' to the ipv6 '[::1]' fixes the dev server proxy

webpack/webpack-dev-server#793 (comment)

Signed-off-by: Tim Etchells <tetchell@redhat.com>
alexmt pushed a commit to argoproj/argo-cd that referenced this issue Oct 9, 2020
Switching the hostname from 'localhost' to the ipv6 '[::1]' fixes the dev server proxy

webpack/webpack-dev-server#793 (comment)

Signed-off-by: Tim Etchells <tetchell@redhat.com>
@artkrylov
Copy link

Solution for this stack: macOS 10.14.6, docker 20.10.0, docker-compose 1.27.4, webpack 4.38.0, preact-cli 3.0.3.

// Example of a webpack config for a preact application.
// preact.config.js

export default {
      
  webpack(config, env, helpers, options) {
    
    // "Gateway" is my Nginx service that routes API requests 
    // and static files inside my Docker network.

    let target = 'http://gateway'

    config.devServer.proxy = [
      {
        path: '/api/v1',
        target
      },
      {
        path: '/static',
        target
      }
    ]

  }

}
// Example of a client-side request.

fetch(`/api/v1/service-name/test`)
  .then((res) => res.json())
  .then((data) => {
    console.log(data)
  })
  .catch(err => {
    console.error(err)
  })
// Example of connecting a static file.
<img src='/static/images/test.jpg' />

@greyshine
Copy link

The issue is 4+ years old. Though it is closed I am wondering why no-one references a documentation where it is (officially) described how it all works.

By the way, I do have the same problem as @gjunkie stated in the first post.
Is there anywhere a good explanation what to put where under what circumstances?

I see variants of webpack usage, path-rewrite, /api/** usage, secure: false, pathRewrite...you name you'll find it but without proper documentation reference.

Well, I made it run on other projects so far, but it is sucky that it always consumes so much time to get it working...

@yxw007
Copy link

yxw007 commented May 16, 2023

Make sure that your request url and port matches that which your webpack-dev-server is running on. So, if your api is located at http://localhost:5000, and your dev server is running on http://localhost:8080, make sure all of your requests are to http://localhost:8080. Its best to make your requests to localhost:8080/api (to avoid conflict with app routes) and use the path rewrite to remove the /api.

Example: Webpack devserver proxy config:

proxy: {
    '/api': {
        target: 'http://localhost:5000',
        pathRewrite: { '^/api': '' },
    },
}

Webpack dev server running on: http://localhost:8080 Desired API endpoint: http://localhost:5000/items

In your app, make the request to: http://localhost:8080/api/items.

This should work. It seems to me that all of the above issues stem from making the request to the API url and port rather than the webpack dev server url and port and using the proxy and path rewrite to direct the request to the API.

Thank you for explaining the problem clearly. Change the interface to be accessed to the IP and port of the dev server, make sure it belongs to the same domain, and then access the correct server IP and port through proxy.

If you understand the process, you'll know how to configure it, right

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests