Which Host header behavior is expected when server.proxy.changeOrigin is disabled?
0 reputation · 18 Nov 2020, 15:17 UTC
0 reputation · 18 Nov 2020, 15:17 UTC
Vite's development server utilizes server.proxy to route API requests to a backend target, leveraging http-proxy to manage headers and bypass CORS restrictions during local development.
A common requirement is ensuring the target server recognizes the request as coming from its own domain. While changeOrigin: true modifies the origin of the host header to match the target URL, the behavior when this option is disabled can vary depending on the backend server's strictness regarding the Host header.
Given a standard Vite configuration, what is the precise mechanism for header propagation when changeOrigin is omitted or set to false? Does Vite preserve the original browser request header, or does it apply a default internal mapping?
31775 reputation · 18 Nov 2020, 23:47 UTC
When server.proxy.changeOrigin is omitted or set to false, Vite’s proxy (powered by http-proxy) forwards the Host header exactly as it was sent by the browser. The proxy does not rewrite it to match the target URL. Consequently, the backend receives the original host value and, if it uses the Host header for virtual‑hosting or SSL validation, the request may be routed incorrectly or rejected.
The default http-proxy configuration preserves incoming headers unless changeOrigin is explicitly enabled. Vite simply forwards the proxy options to the underlying library, so the behavior is governed by http-proxy's default settings.
Host header. For example, a Node/Express app:
const express = require('express');
const app = express();
app.use((req, res, next) => {
console.log('Received Host:', req.headers.host);
next();
});
app.get('*', (req, res) => res.send('ok'));
app.listen(4000, () => console.log('Target listening on 4000'));
export default {
server: {
proxy: {
'/api': {
target: 'http://localhost:4000',
// changeOrigin is omitted or set to false
}
}
}
};
curl -v http://localhost:5173/api/hello
The verbose output shows the Host header that Vite forwards. It should match the value the browser originally sent (e.g., localhost:5173 or whatever the client used).
mitmproxy or Wireshark to capture the outbound request and inspect the Host header.Host: api.example.com for routing or SSL, the request may fail or hit the wrong virtual host.Host header does not match the target domain.Check whether the backend requires a specific Host value. If so, either enable changeOrigin: true or add a custom header rewrite rule in Vite’s proxy configuration.
Use comments to ask for clarification. Post a solution as an answer.
31,775 reputation · 18 Nov 2020, 21:56 UTC
When server.proxy.changeOrigin is false or omitted, Vite's proxy layer does not rewrite the Host header. The request that reaches the target server carries the exact Host value the browser originally sent—typically localhost:5173 or the domain from the frontend origin.
This behavior is inherited directly from http-proxy, which Vite uses under the hood. Since Vite merely passes the proxy configuration to http-proxy-middleware, any option not specified retains its library-default. For changeOrigin, that default is false.
req.headers.host to confirm the value received.curl -H 'Host: localhost:5173' http://localhost:4000/api/test and compare the logged output with the proxied request.If your backend relies on strict host validation (common in production setups with virtual hosting or mutual TLS), you will need to either enable changeOrigin: true or explicitly set the desired Host header via the headers option in the proxy config.