前端开发环境与真实环境的接口联通的那些最佳实践

1. 背景

前端开发的产物通常是 app.jsapp.css ,然后将这些资源放在真实环境域名下进行工作的。 但前端的开发环境通常是本地的 http://localhost:xxx,业务域名可能是 https://xxx.abc.com,两者不在一个域名下在调用接口或者调试时会非常不方便。

加上现在的构建或脚手架工具,如 Vite、Webpack5、Umi 等在开发环境下采用 ES Module 构建,线上采用单文件构建,导致传统的,访问业务域名,然后将资源代理到本地的方式出现问题,所以更合适的方式应该是如何在前端的本地环境下,可以流畅的访问业务域名下的接口。

期待:

2. 实现思路

实现这种方法主要解决:CORS 问题,及 Same-site Cookies 的问题(非登陆态场景不需要解决 Cookie 问题,但很少见此类场景)。 这两个问题,通常业务侧是不能给解决的,所以需要前端自行处理这两个问题。

3. 实现方法

下面罗列下实现期望中,在本地开发环境,顺畅调用业务接口的方法。

3.1 系统级代理实现

针对 CORS 及 Same-site 处理,浏览器级代理是完全无法处理的,当然从调用方向来看也是不合适的,所以需要系统级代理进行拦截重写。

这里推荐 Whistle 或者 Charless 实现。

如 Whistle 可以使用:

perl 复制代码
pattern resCors://* reqCookies://filepath

缺点:

  • 系统级代理,全局受影响,影响网络速度及系统性能。
  • session 的 cookie 需要定期更新,非常繁琐。
  • 部分代理工具无法转发拦截本地请求。

3.2 前端工程侧代理

这个属于比较成熟的方案了,内部通过配置 proxy 可以实现应用及的代理转发。

3.2.1 Webpack OR Umi

Webpack 和 Umi 采用相似的代理方案,底层使用 http-proxy-middleware 实现,可以很方便修改请求和响应,实现 CORS 及 Same-site 的处理。

可以在 webpack.config.js 或者 Umi 的 config.js 中配置:

js 复制代码
export default {
  {
    '/api/': {
      target: "https://xxx.abc.com",
      changeOrigin: true,
      secure:false,
      onProxyReq: (proxyReq) => {
        proxyReq.setHeader(
          'Cookie',
          'sessionId=wzqa6tjqgl;sessionId2=wzqa6tjqgl',
        )
      },
    },
  }
}

3.2.2 Vite

Vite 底层通过 node-http-proxy 实现代理功能。

可以在 vite.config.js 进行配置:

js 复制代码
export default {
  server: {
    proxy: {
      "/api": {
        target: "https://xxx.abc.com",
        changeOrigin: true,
      },
    },
  },
  plugins: [
    {
      name: "append-backend-cookies",
      configureServer(server) {
        server.middlewares.use((req, res, next) => {
          req.headers["Cookie"] = "sessionId=wzqa6tjqgl;sessionId2=wzqa6tjqgl";
          next();
        });
      },
    },
  ],
};

优点:

  • 相比系统级,不会对全局系统代理产生影响,系统性能影响小。
  • 不用额外的其他工具软件支持,简单方便。

缺点:

  • session 的 cookie 需要定期更新,非常繁琐。

3.3 完美方案 Electron 修改 Webview

CORS 的问题本质是浏览器的限制,Same-site 导致的登陆 Cookies 无法携带也是浏览器的限制,那直接把浏览器的限制给去掉不就可以迎刃而解了。这样不需要 api 的域名转发了,也不需要代理了,直接在 localhost 下调用 xxx.abc.com 就可以了。且在 Electron 中也可以正常安装浏览器插件,像 React-Devtools 完全正常使用。

早期 Electron 版本只需要 webSecurity: false 就可以解决我们的问题,但在 Chrome 94 版本不再放行,无法再携带 Cookies,也就是 Electron v14 之后的版本无法通过 webSecurity: false 来禁用这些问题。

新版本(v27),通过复写 onHeadersReceived 实现:

js 复制代码
function createWindow() {
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      webSecurity: false,
    },
  });

  win.loadURL("https://localhost:3000");
  // win.webContents.openDevTools();
}

function disableSamesiteCookies(filter = ["*://*/*"]) {
  session.defaultSession.webRequest.onHeadersReceived(
    { urls: filter },
    (details, callback) => {
      const newCookies = [];

      details?.responseHeaders?.["set-cookie"]?.map((item) =>
        newCookies.push(item.split("; ")[0] + "; Secure; SameSite=None")
      );
      details.responseHeaders["set-cookie"] = newCookies;

      callback({ cancel: false, responseHeaders: details.responseHeaders });
    }
  );
}

app.whenReady().then(() => {
  createWindow();
  disableSamesiteCookies();

  //  ......
});

优点:

  • 几乎全是优点。

缺点:

  • 需要额外开启 electron 项目。

4. 链接

原文地址: Github

相关推荐
WooaiJava21 分钟前
AI 智能助手项目面试技术要点总结(前端部分)
javascript·大模型·html5
爱喝白开水a40 分钟前
前端AI自动化测试:brower-use调研让大模型帮你做网页交互与测试
前端·人工智能·大模型·prompt·交互·agent·rag
Never_Satisfied40 分钟前
在JavaScript / HTML中,关于querySelectorAll方法
开发语言·javascript·html
董世昌4141 分钟前
深度解析ES6 Set与Map:相同点、核心差异及实战选型
前端·javascript·es6
WeiXiao_Hyy1 小时前
成为 Top 1% 的工程师
java·开发语言·javascript·经验分享·后端
吃杠碰小鸡2 小时前
高中数学-数列-导数证明
前端·数学·算法
kingwebo'sZone2 小时前
C#使用Aspose.Words把 word转成图片
前端·c#·word
Serene_Dream2 小时前
JVM 并发 GC - 三色标记
jvm·面试
xjt_09012 小时前
基于 Vue 3 构建企业级 Web Components 组件库
前端·javascript·vue.js
我是伪码农2 小时前
Vue 2.3
前端·javascript·vue.js