Setting "proxy" in package.json should proxy WebSockets to specified server.
(As documented here: "The proxy option supports HTTP, HTTPS and WebSocket connections.")
Proxy does not work for WebSocket connections.
No time for this atm. ¯\_(ツ)_/¯
Did it work in 1.x? Or is this a regression?
Create src/setupProxy.js
, with:
const proxy = require("http-proxy-middleware")
module.exports = app => {
app.use(proxy("/websocket", {target: "http://localhost:8080", ws: true}))
}
In 1.x, it was possible to specify more advanced options, including "ws":true
.
Though I don't know what the handling by the simple "proxy":
< url > was.
OK, sounds like this isn't a regression but a proposal to auto-detect and proxy websockets in the simple proxy mode.
At minimum, reality is out of sync with the documentation.
(Ended up wasting a couple hours trying to figure out why I couldn't connect.)
Though I would recommend making WebSocket proxying work by default.
It was supposed to work in 1.x too.
I reproduce with issue.
app.use(proxy('/ws', {
target: 'http://localhost:3007',
ws: true,
}));
[HPM] Upgrading to WebSocket
events.js:167
throw er; // Unhandled 'error' event
^
Error: read ECONNRESET
at TCP.onStreamRead (internal/stream_base_commons.js:111:27)
Emitted 'error' event at:
at emitErrorNT (internal/streams/destroy.js:82:8)
at emitErrorAndCloseNT (internal/streams/destroy.js:50:3)
at process._tickCallback (internal/process/next_tick.js:63:19)
I can confirm that the following setup worked in 1.x:
"proxy": {
"/api": {
"target": "ws://localhost:4000",
"ws": true
}
}
but this no longer works in 2.1.1's package.json
:
"proxy": "ws://localhost:4000"
I get the following error message upon npm start
:
When "proxy" is specified in package.json it must start with either http:// or https://
That said, I will be happy to test any fix you throw at my direction.
Hey,
I tried to investigate some time to analyze this issue and found a possible fix. Would be great if some of you could test it. Once it works for you too, I will open a PR.
https://github.com/mxschmitt/create-react-app/commit/acc5ab13da20d777012f53578b76266d5521cff0
To test it, simply edit the following file: node_modules/react-dev-utils/WebpackDevServerUtils.js
and add to line 327
to the return condition req.upgrade ||
like in the commit above.
Best regards
Max
@mxschmitt, thank you for your email.
I've tried your patch but it did not work for me. I was still receiving error message:
When "proxy" is specified in package.json it must start with either http:// or https://
.
So I've hacked the following fix and it works for my setup:
ivosh@1fa22ae7a2c54903f6c69f60f8b29c24487ff812
I've also tried to incorporate your patch into it and observed no difference (works with and also without).
@ivosh You don't have to use ws://
as protocol for your websocket. Just use http://
which will work fine in my case.
@mxschmitt, you are right, thank you for pointing this out. So in my case, even when all communication happens over websockets, specifying "proxy": "http://localhost:4000"
is sufficient for the communication to be proxied.
Your change is not needed in my setup.
+1'ing the change @mxschmitt is proposing, this does fix the issue for me.
For background, the problem locally is that firefox is sending 'text/html' in 'Accept' when opening the websocket connection, which causes the default proxy heuristic to -not- proxy the request:
return (
req.method !== 'GET' ||
(mayProxy(pathname) &&
req.headers.accept &&
req.headers.accept.indexOf('text/html') === -1)
);
I agree the presence of the 'upgrade' header should force proxying just like a non-GET request, unless there's a case I'm missing.
Yey, the stale bot has closed my PR: #5841....
I've been wrestling with this issue for a while now, and the workarounds are very annoying, especially when you have cookies involved. Is there any reason why #5841 isn't being merged? It looks like one of the builds failed, but it seems to be an issue completely unrelated to the code change in that PR.
@mxschmitt maybe if you add a comment to the code in your PR, the CI will rerun and hopefully there won't be any build issues this time?
@hamidnoei This workaround has already been discussed.
@avdeev Alexey, have you found a solution for the issue you described in this comment: https://github.com/facebook/create-react-app/issues/5280#issuecomment-428199778 ? I have got the same.
Any updates on this?
I was having a similar problem of not being able to proxy websocket connections and did a little digging. My finding was that the context
property being returned by prepareProxy
in WebpackDevServerUtils.js
is returning undefined
for websocket connections. This is because the standard headers for a websocket created through the WebSocket
class constructor do not include an Accept
header. Since this function returns undefined
, which is equivalent to false
, the websocket connection is not proxied. I don't know if this is the place to fix the issue, but I managed to get it working for myself by adding a check for a websocket request. Something like checking for the Upgrade
header being set to "websocket"
:
function(pathname, req) {
return (
req.method !== "GET" ||
(mayProxy(pathname) &&
((req.headers.upgrade && req.headers.upgrade === "websocket") ||
(req.headers.accept && req.headers.accept.indexOf("text/html") === -1)))
);
}
I had a problem where I couldn't proxy requests (in development) to my own websocket (socket-io) server.
I followed the steps here: create-react-app proxying requests in dev, my setupProxy.js
looked like this:
The below did not work for proxying a websocket connection:
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function (app) {
app.use(
'/api',
createProxyMiddleware({
target: 'http://localhost:5011',
}),
);
app.use(
'/socket-io',
createProxyMiddleware({
target: 'http://localhost:5011',
ws: true,
}),
);
};
However, the hot reloading wouldn't work because somehow this interfered with webpack dev servers websocket connection. I would see this error in the console:
[HPM] Error occurred while trying to proxy request /sockjs-node from localhost:3000 to http://localhost:5011 (ECONNRESET) (https://nodejs.org/api/errors.html#errors_common_system_errors)
I got this working by doing the following:
const isDev = process.env.NODE_ENV === 'development';
const socket = isDev
? io.connect('http://localhost:5011', { path: '/socket-io' })
: io.connect({ path: '/socket-io' });
Hope this helps someone out! Let me know if there's a better way to do this 👍
Why is it still not resolved in 2020? Why fixing PR #5841 was rejected? @Timer @gaearon
+1
+1
FYI according to #6497 there was a new PR #6515 but that has been closed without comment after the stale bot flagged it again.
+1
Workaround: Use Firefox, for some reason this feature is not broken on Firefox.
I typically do my local development on Firefox, and websocket proxying works there out of the box, and I was surprised to see that this was broken on Chrome, wasted alot of hours on this bug
The docs for proxy linked to in the original description have moved here.
Verified this is broken in Chrome 77.0.3865.75 (Official Build) (64-bit)
and working in FireFox 76.0.1 (64-bit)
Agree with @Kent-H - preferred behavior would be "work out of the box"
Interesting its a Chrome only issue
Burned hours thinking it was my code preventing the socket connection.
I'd give big nerd creds to anyone involved in fixing it !
Current workaround:
Create
src/setupProxy.js
, with:const proxy = require("http-proxy-middleware") module.exports = app => { app.use(proxy("/websocket", {target: "http://localhost:8080", ws: true})) }
can u tell me how can i use setupProxy.js and i removed proxy from packege.json so how can i redireect my api to proxy
I can also confirm this is broken in chrome but working in firefox. This is probably unrelated, but I have HTTPS=true
, which is working for wss
on firefox. I say it's unrelated b/c chrome breaks when using ws
or wss
.
At the very least, the docs should be updated to indicate that this is currently broken for websockets in chrome. It's a little misleading to say that it works websockets when that's only true for certain browsers.
I also have the same issue, proxy not working for Chrome but is for Firefox.
+1
any news on the issue?
+1
Most helpful comment
Current workaround:
Create
src/setupProxy.js
, with: