关于webpack中proxy的总结

今天有人问我关于webpack中proxy相关的问题,于是我想着把proxy好好总结一下,分享给更多的人。

本文大纲:

关于webpack中proxy的总结_第1张图片

1、用途

首先声明一下:proxy只用于开发阶段,说白了就是用于本地开发调试。
在开发阶段中,由于浏览器同源策略的原因,当本地访问后端就会出现跨域请求的问题,所以在webpack中配置一个开发服务器webpack-dev-server(后面简称devServer服务器),在devServer服务器中配置proxy,相当于浏览器发出请求时,会先到本地服务器devServer,然后devServer服务器做一个代理转发到对应的后端服务器上。注意:跨域是浏览器的安全策略,服务器之间是不存在跨域的
我们先看一下简单的代理配置代码。

// ./webpack.config.js
module.exports = {
    // 开发服务器配置
    devServer: {
        port: 8080,
        proxy: {
            '/ws_payment': {
                target: 'http://api.pay.com'
            }
        }
        // ...
    }
}

在项目中的应用,下面的请求会请求到 http://api.pay.com/ws_payment/h5/group/verify上

   submit () {
      this.$http
        .post({
         // /ws_payment的使用,
          url:/ws_payment/h5/group/verify’,
          data: this.getSendData(),
        })
        .then((res) => {
          if (res.code === '1') {
            location.href = res.data.payUrl;
          } else {
            this.$message.error(res.msg);
          }
        })
        .catch((reason) => {
          this.$message.error(reason);
        });
    },

那有人就会有疑问了,代码上线之后呢,这样的请求怎么处理? 处理的方式有很多中,我们项目中的处理方式是配置nginx代理(其实原理和本文讲的proxy代理是一样的)。

2、相关的代理匹配规则

常用的属性有四个

  • target:表示的是代理到的目标地址
  • pathRewrite
  • secure:默认情况下不接收转发到https的服务器上,如果希望支持,可以设置为false
  • changeOrigin:它表示是否更新代理后请求的 headers 中host地址

关于更多的配置信息请查看:webpack官网

// webpack.config.js
 devServer: {
    proxy: { // 配置代理(只在本地开发有效,上线无效)
      "/ws_payment": { // 这是请求接口中要替换的标识
        target: "http://api.pay.com", // 被替换的目标地址,即把 /api 替换成这个
        pathRewrite: {"^/api" : ""}, // 如果不希望传递/api,则需要重写路径,这个时候请求路径中就没有/api了
        secure: false, // 若代理的地址是https协议,需要配置这个属性
        changeOrigin: true, // 加了这个属性,那后端收到的请求头中的host是目标地址 target
      }
    } 
  }

默认情况下,代理时会保留主机头(host)的来源,可以将 changeOrigin 设置为 true 以覆盖此行为。
关于host,请看我另外一篇文章:http请求头中的origin、referer、host

重点说一下changeOrigin 设置为 true的情况

changeOrigin 设置为 false时
假设你的前端服务器是 http://localhost:3000,后端是 http://localhost:8082。
那么后端通过 request.getHeader(“Host”) 获取依旧是 http://localhost:3000。

changeOrigin 设置为 true时
如果你设置了 changeOrigin: true,那么后端通过 request.getHeader(“Host”) 获取才是 http://localhost:8082。代理服务器此时会根据请求的 target 地址修改 Host。

注意
但是我在本地通过F12打开浏览器的request Header 的 Host,发现无论怎么修改 changeOrigin,它均为前端服务器地址。
如图:
关于webpack中proxy的总结_第2张图片
会发现Host的域名端口号和前端资源地址Referer的域名端口号一致。(关于Host和Referer的概念请看我这篇博客:http请求头中的origin、referer、host)。

是不是changeOrigin: true 设置无效?
其实不然。而且,设置已经生效了,只是浏览器不会直观地显示给你。
(接着http://localhost:3000和http://localhost:8082的这个例子说)
你需要通过后端进行 request.getHeader(“Host”) 打印,你就能发现区别了。
当不设置 changeOrigin 的时候,后端输出 http://localhost:3000
当设置 changeOrigin: true 的时候,后端输出 http://localhost:8082

是因为,浏览器只是将第一层请求显示给你(因为第一层请求是请求的本地服务器,域名、端口号和前端页面的域名、端口号都是一致的),第一层请求也就是发给代理服务器的请求,而修改 Host 的工作是代理服务器做的,浏览器当然不会显示 Host 已经被修改的状态!

3、原理

proxy工作原理实质上是利用http-proxy-middleware 这个http代理中间件,实现请求转发给其他服务器
举个例子:

在开发阶段,本地地址为http://localhost:3000,该浏览器发送一个前缀带有/api标识的请求到服务端获取数据,但响应这个请求的服务器只是将请求转发到另一台服务器中

const express = require('express');
const proxy = require('http-proxy-middleware');

const app = express();

app.use('/api', proxy({target: 'http://www.example.org', changeOrigin: true}));
app.listen(3000);

// http://localhost:3000/api/foo/bar -> http://www.example.org/api/foo/bar

参考:
https://blog.csdn.net/qq_39291919/article/details/108807111
https://blog.csdn.net/qq_40409143/article/details/116517080

你可能感兴趣的:(webpack系列,工作学习总结,笔记,proxy,webpack中的proxy,proxy的用途,webpack中proxy配置,proxy的原理)