你也许并不需要在每个项目中配置proxy,带你20行代码实现一个反向代理的谷歌插件(最简版本)

142 阅读3分钟

完整代码可以参考: github.com/electroluxc…

通常项目中的反向代理

一版来说,我们作为前端在与后端联调的时候,为了避免浏览器的跨域错误,会在打包工具vite或者webpack中,配置反向代理工具

这个时候流程图如下

flowchart TD
    C[webpack等打包工具] -->|开启服务| E[前端地址]
    E -->|起一个middleware服务拦截指定请求代理| D[后端地址]

这个时候其实可以说我们只有两个地址,也就是在前端地址中拦截后端的middleware请求,然后代理到前端地址

浏览器插件中的反向代理

而在浏览器插件中,我们的实现方式会有所不同,最显而易见的区别是我们会有三个地址,因为如果像在上图一样在 浏览器插件中直接进行串行地址,可能会有问题,

你知道的,我们在 定义前端路由有时候会加上一些兜底。

而没有了webpack,vite等打包工具做聚合,那么串行起来有可能后端代理的地址会命中前端兜底的路由,导致所有的后端请求寄了

{
    match: "*",
    component: 404/403/other
}

这是设计三个地址的原因,其中我们会有一个中心策略去统筹前端和后端,将他们放在同一个地址上,实现思路可以参考下面

flowchart TD
    C[浏览器代理插件] -->|代理地址| D[前端]
    C -->|代理地址| E[后端地址]

    D -->|聚合| F[另一个地址]
    E -->|聚合| F

浏览器插件代码实现

浏览器插件代码实现

首先在 manifest.json 中 的 permissions 去申请权限, 然后定义 host_permissions 接着定义 background 的脚本地址, 最后把内容填进去就好

manifest.json 示例如下

{
  "name": "simple-modify-proxy",
  "version": "0.1",
  "manifest_version": 3,
  "description": "",
  "author": "Electrolux",
  "permissions": [
    "proxy"
  ],
 
  "background": {
    "service_worker": "js/background.js"
  },
  "host_permissions": [
    "<all_urls>"
  ]
}

background.js 中, 代码写法如下,20行代码左右就可以实现了,简单说一下 思路,

  • 其中 FindProxyForURL 这个名字不能够改变, 一旦改变那么 proxy 不会生效,这点需要尤其注意.然后 FindProxyForURL 中不能够有注释,不然注入的时候会有问题
  • 这里的命中格式需要你根据自己的项目进行修改,注意一下下面的代码可能会对你浏览的其他网页有影响,所以当你需要的时候再打开这个插件
  • 这里只提供最简单的示例,更多的api示例可以参考 google的开发文档 developer.chrome.com/docs/extens…
console.log("background.js loaded")
console.log(chrome)

var FindProxyForUrl = function FindProxyForURL(url, host) {
    if(!window.location.href.includes("front-test")){
      return 'DIRECT';
    }
    if (shExpMatch(url, "*api*")) {
        // 你的api后端地址
        return 'PROXY localhost:8098';
    }

    if (shExpMatch(url, "*front-test*")) {
        // 你的前端地址
        return 'PROXY localhost:5500';
    }
  return 'DIRECT';
}
var configPAC = {
    mode: "pac_script",
    pacScript: {
      data:FindProxyForUrl.toString()
    }
};
chrome.proxy.settings.set(
    {value: configPAC, scope: 'regular'},
    function() {}
);

后端示例

var express = require("express");
var app = express();
let httpServer = http.createServer(app);
app.get("/api/get", function (req, res, next) {
	res.send({
		code: 200,
		message: "success"
	});
});


前端

这里我直接用live server了,这是个vscode 插件,直接安装就可以了, 然后我们访问携带 front-test 的就可以访问到我们的界面了。例如 front-test.cn,

front-test.com, www.front.com

最后我们可以简单用一个fetch请求测试一下, 可以看到并没有跨域错误,并且成功命中了

fetch("/api/get").then(e=>e.json()).then(e=>{console.log(e)})

image-20250108160319405.png