Cross-Origin Resource Sharing (CORS) issues are common technical obstacles that front-end developers often encounter. When the browser executes cross-origin requests, due to security policy restrictions, CORS errors will occur, leading to request failures. For developers using Vite to build projects, configuring Proxy to solve CORS issues is an efficient and commonly used solution. This article will deeply explore the configuration principles and specific practices of Proxy in Vite, helping developers quickly and securely bypass CORS restrictions and achieve smooth interaction of front-end and back-end data.
Vite Proxy
You can find the relevant Proxy settings in the official documentation of Vite.
export default defineConfig({ server: { proxy: { // String shorthand notation: http://localhost:5173/foo -> http://localhost:4567/foo '/foo': 'http://localhost:4567', // Option-based notation: http://localhost:5173/api/bar -> http://jsonplaceholder.typicode.com/bar '/api': { target: 'http://jsonplaceholder.typicode.com', changeOrigin: true, rewrite: (path) => path.replace(/^\/api/, ''), }, // Regular expression notation: http://localhost:5173/fallback/ -> http://jsonplaceholder.typicode.com/ '^/fallback/.*': { target: 'http://jsonplaceholder.typicode.com', changeOrigin: true, rewrite: (path) => path.replace(/^\/fallback/, ''), }, // Using a proxy instance '/api': { target: 'http://jsonplaceholder.typicode.com', changeOrigin: true, configure: (proxy, options) => { // proxy is an instance of 'http-proxy' } }, // Proxying WebSockets or socket.io notation: ws://localhost:5173/socket.io -> ws://localhost:5174/socket.io '/socket.io': { target: 'ws://localhost:5174', ws: true, }, }, },})
The official documentation clearly explains how to use Proxy, and you can start using it by adding it to vite.config.js
.
Pure String Notation
It is relatively simple, writing the proxy path and the target path together.
export default defineConfig({ server: { proxy: { '/foo': 'https://api-example.com', }, },})
When running the project, the AJAX might be written like this:
axios.get('/foo') .then((res) => { console.log(res); })
The request seen on the web page is http://localhost:5173/foo
, and the actual request is https://api-example.com/foo
.
Option-Based Notation
It is more complex and allows you to adjust the proxy settings through options.
export default defineConfig({ server: { proxy: { '/api': { target: 'https://api-example.com', changeOrigin: true, rewrite: (path) => path.replace(/^\/api/, ''), }, }, },})
target
: The target address of the proxy.changeOrigin
: Whether to change the Host header of the original request.rewrite
: Rewrite the path.
changeOrigin
is used to adjust the origin
. When the target API checks the origin
, it needs to be set to true
, otherwise the request will be rejected. It mainly rewrites the origin
in the header.
rewrite
rewrites the path, converting the request path into the path of the target API.
For example, if the target API is https://api-example.com/foo
, the AJAX might be written like this:
axios.get('/api/foo') .then((res) => { console.log(res); })
After rewriting the path through rewrite
, the browser sees http://localhost:5173/api/foo
, and the actual request is https://api-example.com/foo
.
Regular Expression Notation
It is similar to the option-based notation, which is mentioned in the official documentation.
export default defineConfig({ server: { proxy: { '^/fallback/.*': { target: 'https://api-example.com', changeOrigin: true, rewrite: (path) => path.replace(/^\/fallback/, ''), }, }, },})
When initiating a request http://localhost:5173/fallback
, the actual request is https://api-example.com
.
Proxy Instance
It is an instance of http-proxy
, and you can adjust its settings through the configure
option.
export default defineConfig({ server: { proxy: { '/api': { target: 'https://api-example.com', changeOrigin: true, configure: (proxy, options) => { ... } }, }, },})
Configuring configure
allows you to view the Proxy request records.
export default defineConfig({ server: { proxy: { '/api': { target: 'https://api-example.com', changeOrigin: true, configure: (proxy, options) => { proxy.on('proxyReq', (proxyReq, req, _res) => { console.log('Sending Request to the Target:', options.target + proxyReq.path); }); } }, }, },})
You can also view the responses and errors:
export default defineConfig({ server: { proxy: { '/api': { target: 'https://api-example.com', changeOrigin: true, configure: (proxy, options) => { proxy.on('proxyReq', (proxyReq, req, _res) => { console.log('Sending Request to the Target:', req.method, options.target + proxyReq.path); }); proxy.on('proxyRes', (proxyRes, req, res) => { console.log('Receiving Response from the Target:', req.method, options.target + req.url); }); proxy.on('error', (err, req, res) => { console.log('Error Occurred:', err); }); } }, }, },})
You can see the request records in the terminal:
Sending Request to the Target: GET https://api-example.com/apiReceiving Response from the Target: GET https://api-example.com/api
For more Proxy options, you can refer to http-proxy.
Common Problems
Proxy is only used in the development environment. In the production environment, it cannot work unless a back-end server is set up. Proxy is convenient for developers to connect to APIs in the development environment, but it cannot replace the back-end server. When encountering CORS issues, they still need to be handled on the back-end.