Webpack Proxy 工作原理与跨域解决

理解 Webpack Dev Server 代理机制及其解决跨域的原理

问题

Webpack Proxy 是如何工作的?为什么它能解决跨域问题?

解答

跨域问题的本质

浏览器的同源策略限制了不同源之间的请求。但这个限制只存在于浏览器端,服务器之间的通信不受此限制。

浏览器 --X--> 目标服务器 (跨域,被浏览器拦截)
浏览器 ----> 同源服务器 ----> 目标服务器 (OK)

Webpack Proxy 工作原理

Webpack Dev Server 内部使用 http-proxy-middleware 创建代理服务器:

浏览器 (localhost:8080)
    |
    | 同源请求

Webpack Dev Server (localhost:8080)
    |
    | 服务器转发 (不受同源策略限制)

目标 API 服务器 (api.example.com)

配置示例

// webpack.config.js
module.exports = {
  devServer: {
    proxy: {
      // 匹配 /api 开头的请求
      '/api': {
        target: 'http://api.example.com', // 目标服务器
        changeOrigin: true, // 修改请求头中的 host
        pathRewrite: {
          '^/api': '' // 重写路径,去掉 /api 前缀
        }
      }
    }
  }
}

请求转换过程

// 前端代码发起请求
fetch('/api/users')

// 实际请求流程:
// 1. 浏览器请求: http://localhost:8080/api/users (同源)
// 2. Dev Server 转发: http://api.example.com/users (服务器间通信)
// 3. 响应原路返回给浏览器

简化版代理实现

const http = require('http')
const httpProxy = require('http-proxy')

// 创建代理服务器
const proxy = httpProxy.createProxyServer()

const server = http.createServer((req, res) => {
  // 匹配需要代理的路径
  if (req.url.startsWith('/api')) {
    // 转发到目标服务器
    proxy.web(req, res, {
      target: 'http://api.example.com',
      changeOrigin: true
    })
  }
})

server.listen(8080)

changeOrigin 的作用

// changeOrigin: false (默认)
// 请求头 Host: localhost:8080

// changeOrigin: true
// 请求头 Host: api.example.com
// 某些服务器会校验 Host,需要开启此选项

关键点

  • 同源策略只限制浏览器:服务器之间的 HTTP 请求不受限制
  • 代理本质是请求转发:Dev Server 作为中间人,接收浏览器请求后转发给目标服务器
  • 仅限开发环境:生产环境需要 Nginx 反向代理或后端配置 CORS
  • changeOrigin 修改 Host:让目标服务器认为请求来自它自己
  • pathRewrite 重写路径:可以去掉或修改请求路径前缀