http-proxy-middleware
http-proxy-middleware copied to clipboard
http-proxy-middleware v3 adds a '/' before query parameters ending up with 404
Checks
- [X] I understand project setup issues should be asked on StackOverflow or in GitHub Discussions.
- [X] I updated to latest
http-proxy-middleware.
Describe the bug (be clear and concise)
With the following
app.use(
createProxyMiddleware('/api/v1/xyz', {
target: 'https://example.com/api/v1/xyz',
changeOrigin: true,
})
);
if a request is being made https://myapp.com/api/v1/xyz?param1=value the proxied request is translating to https://example.com/api/v1/xyz/?param1=value resulting in 404. ( Extra / is being added )
This was not the case with v2 and even with v3 legacy mode.
Step-by-step reproduction instructions
1. Add proxy as described above
2. send the request with query params
Expected behavior (be clear and concise)
No "/" should be added,
How is http-proxy-middleware used in your project?
[email protected] proxy-app
├── [email protected]
└─┬ [email protected]
└─┬ [email protected]
└── [email protected]
What http-proxy-middleware configuration are you using?
app.use(
createProxyMiddleware('/api/v1/xyz', {
target: 'https://example.com/api/v1/xyz',
changeOrigin: true,
})
);
### What OS/version and node/version are you seeing the problem?
```shell
Windows 11, Node 20
Additional context (optional)
No response
same here
@chimurai mentioned in https://github.com/chimurai/http-proxy-middleware/issues/985#issuecomment-2067656422 that this is an upstream issue in the (unmaintained) http-proxy library. I only started seeing it after upgrading http-proxy-middleware from 2.0.6 to 3.0.0 though, which use the same http-proxy version, so that's a bit odd, but perhaps the issue somehow surfaced with #731 ?
Workaround (first attempt):
createProxyMiddleware({
target: `https://otherhost/api`,
changeOrigin: true,
pathRewrite: (path) => path.replace(/\/$/, ""),
});
That doesn't handle URLs with query strings or hashes though.. Second attempt using lookahead to remove /'s followed by either ? or end of line:
createProxyMiddleware({
target: `https://otherhost/api`,
changeOrigin: true,
pathRewrite: (path) => path.replace(/\/(?:(?=\?)|$)/, ""),
});
I have a feeling this one might not be perfect either though :/
dupe of https://github.com/chimurai/http-proxy-middleware/issues/1000
Indeed related to change in https://github.com/chimurai/http-proxy-middleware/pull/731
Specifically: https://github.com/chimurai/http-proxy-middleware/pull/731/files#diff-07e6ad10bda0df091b737caed42767657cd0bd74a01246a1a0b7ab59c0f6e977L118
trailing slash issue should (ideally) be fixed in http-proxy
trailing slash issue should (ideally) be fixed in http-proxy
The issue is that http-proxy hasn't been updated in 4 years... But this issue doesn't occur in the legacy version, so are you sure it happens in http-proxy
Please fix this issue, other wise it will impact usage of latest version
Hi @mnadeem. It's an open source project. You are welcome fix it upstream or suggest a fix.
I am more wondering why this does occur with the createProxyMiddleware, but not the legacyCreateProxyMiddleware. Trying to investigate this a bit more...
The legacy behaviour is on L30:
https://github.com/chimurai/http-proxy-middleware/blob/897611af512ffaf6add1601585952356fde8aec5/src/http-proxy-middleware.ts#L124-L131
To help investigation, it would be helpful to provide a minimal reproduction of the issue.
I ran into this issue after upgrading from v2 to v3, where an extra / was being added before query parameters. On v2, a configuration like:
app.use(
'/xyz.json',
createProxyMiddleware({
target: 'https://example.com/',
changeOrigin: true,
})
);
would correctly proxy https://myapp.com/xyz.json to https://example.com/xyz.json.
After upgrading to v3 and switching to the new API:
app.use(
'/xyz.json',
createProxyMiddleware({
target: 'https://example.com/xyz.json',
changeOrigin: true,
})
);
the proxied request became https://example.com/xyz.json/, causing a 404 on our end.
As a workaround, I’ve explicitly controlled the path using pathRewrite and req.baseUrl:
app.use(
createProxyMiddleware('/xyz.json', {
target: 'https://example.com/',
changeOrigin: true,
pathRewrite: (_path, req) => req.baseUrl,
})
);
This ensures that the trailing slash isn’t appended, and matches what the previous v2 version outputted.
@adammccullagh I would suggest using req.originalUrl. e.g. /_next/static/css/app/layout.css resolved into /_next/static if it's checks on the path: /_next/:slug
The legacy behaviour is on L30:
http-proxy-middleware/src/http-proxy-middleware.ts
Lines 124 to 131 in 897611a
/** * Incorrect usage confirmed: https://github.com/expressjs/express/issues/4854#issuecomment-1066171160 * Temporary restore req.url patch for {@link src/legacy/create-proxy-middleware.ts legacyCreateProxyMiddleware()} * FIXME: remove this patch in future release */ if ((this.middleware as unknown as any).__LEGACY_HTTP_PROXY_MIDDLEWARE__) { req.url = (req as unknown as any).originalUrl || req.url; }To help investigation, it would be helpful to provide a minimal reproduction of the issue.
Hi @chimurai, Sorry, completely forgot about creating a repro, here you go https://github.com/Netail/repro-http-proxy-middleware :) The README explains how to reproduce the issue