列举几种常见的前端代理方案

1,783 阅读3分钟

起因

前段时间因为项目中前端解决跨域及node服务端需要进行本地调试代码等问题,多次接触了前端代理相关的技术方案,现在特地梳理下目前常见的几种前端代理解决方案。

目的

前端常用于解决跨域问题及debug调试等,当然代理的作用不止于解决跨域问题等

代理介绍

代理(Proxy)也称网络代理,是一种特殊的网络服务,允许一个(一般为客户端)通过这个服务与另一个网络终端(一般为服务器)进行非直接的连接。

提供代理服务的电脑系统或其它类型的网络终端称为代理服务器(Proxy Server)。一个完整的代理请求过程为:客户端首先与代理服务器创建连接,接着根据代理服务器所使用的代理协议,请求对目标服务器创建连接、或者获得目标服务器的指定资源。

代理服务器的基本行为就是接收客户端发送的请求后转发给其他服务器。代理不改变请求URI,并不会直接发送给前方持有资源的目标服务器。

持有资源实体的服务器被称为源服务器。从源服务器返回的响应经过代理服务器后再传给客户端。

常见方案

方案一:webpack的devServer.proxy解决跨域问题

webpack.config.js

module.exports = {
  //...
  devServer: {
    proxy: {
      '/api': {
        target: 'http://localhost:3000',
        pathRewrite: { '^/api': '' },
      },
    },
  },
};

现在,对 /api/users 的请求会将请求代理到 http://localhost:3000/api/users。

方案二:node中间件解决跨域问题

1.安装node-proxy-middleware包

2.基本用法

var express=require('express');
var proxy=require('http-proxy-middleware');
var app=express();
app.use(
'/api',
  proxy(
    {
      target:'http://www.example.org',
      changeOrigin:true
    }
  )
);
app.listen(3000);

此时所有/api的请求都将代理至www.example.org

方案三:抓包类工具配置代理进行代码调试

常用的抓包工具有Wireshark、Fiddler、Charles。这里以Charles举例:

1.在需要进行转发的api请求上右击选择Map Remote...

image.png

2.配置转发到本地的路径

image.png

然后再访问线上环境,就会发现已经将请求转发到本地来了,这样我们就可以进行奇奇怪怪的debug调试了…

方案四:SwitchyOmega等调试本地代码

Chrome的相关插件:Proxy SwitchySharp、SwitchyOmega、ReRes

Firefox的相关插件:FoxyProxy、Autoproxy

这里演示SwitchyOmega + whistle 将线上请求代理至本地进行代码调试的过程:

1.首先npm i whistle -g安装whistle

2.安装whistle之后w2 start,然后浏览器打开http://127.0.0.1:8899 ,配置代理规则

image.png

格式为: 线上目标地址 + 空格 + 要代理到的服务器地址

3.打开SwitchyOmega的选项,配置代理服务器地址及端口号等

4.开启SwitchyOmega你刚才配置的代理服务就可以将线上请求代理至本地进行代码调试了

方案五:nginx

大致用法:

location /proxy2 {
	proxy_pass http://127.0.0.1:8099;  # 无uri
}

有如下请求:http://localhost:8088/proxy2/index.html

即访问 http://localhost:8088/proxy2/index.html ,实际请求路径为http://127.0.0.1:8099/proxy2/index.html

nginx配置文件大概长这样:

events {
    worker_connections  1024;
}
http {
    server {
        listen       8088;
        server_name  localhost;
		
		
		location /proxy {
			proxy_pass http://127.0.0.1:8099/svr1;  # uri为'/svr1'
		}
		
		location /proxy2 {
			proxy_pass http://127.0.0.1:8099;	# 无uri
        }
		
		
		location /v1 {
			proxy_pass http://127.0.0.1:8099;
			rewrite '^/v1/(.*)$' /$1 break;
		}
		location /v2 {
			proxy_pass http://127.0.0.1:8099$1;
		}
		location /v3 {
			proxy_pass http://127.0.0.1:8099$request_uri;
		}
		location ~ /v4/([\d]+)/(.*) {
			proxy_pass http://127.0.0.1:$1/$2?$query_string;
        }
		location ~ /v5/([\d]+) {
			proxy_pass http://127.0.0.1:$1;
			rewrite ^/v5/([\d]+)/(.*)$ /$2 break;
        }
		location /v6 {
			if ($request_uri ~* ^/(.*)$) {
				proxy_pass http://127.0.0.1:8099/$1;
			}
        }
		
    }
	
	# 此server模拟被代理的服务。
	server {
		listen       8099;
		server_name  localhost;
		
		location / {
			add_header request $request;
			#  直接返回请求路径。也就是通过Nginx代理后,实际请求的url。
			default_type text/html; return 200 $host:$server_port$request_uri;
		}
	}
}