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

article/2024/3/2 11:24:02

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 可以使用:

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 中配置:

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 进行配置:

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 实现:

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. 链接

  • https://github.com/http-party/node-http-proxy#options
  • https://developers.google.com/search/blog/2020/01/get-ready-for-new-samesitenone-secure?hl=zh-cn
  • https://www.chromium.org/updates/same-site/
  • https://github.com/GoogleChromeLabs/samesite-examples
  • https://releases.electronjs.org/releases/stable?version=14
  • https://github.com/lecepin/Debugging-env-browser
  • https://webpack.js.org/configuration/dev-server/#devserverproxy
  • https://vitejs.dev/config/server-options.html#server-proxy
  • https://github.com/chimurai/http-proxy-middleware#options

原文地址: Github


http://www.ngui.cc/article/show-1753822.html

相关文章

虽有局限性,但在Windows 11上运行Android应用程序是一个不错的新功能

在Windows 11上,Android的Windows子系统(WSA)是一个集成,允许你在笔记本电脑或台式机上与Windows应用程序一起运行Android应用程序,在本指南中,我将向你展示入门步骤。官方规定,你只能从亚马逊应用商店安装应用程序,但也可以使用安卓调试桥(ADB)工具侧载安卓应用程序…

【深度学习】性能监控

性能监控 判断系统,然后再监控程序运行期间机器的性能 import psutil import matplotlib.pyplot as plt import time import matplotlib import subprocess import platform import os try:import GPUtilimport pynvml except ImportError as e:print(f"导入…

【开源】基于JAVA的医院门诊预约挂号系统

项目编号: S 033 ,文末获取源码。 \color{red}{项目编号:S033,文末获取源码。} 项目编号:S033,文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 功能性需求2.1.1 数据中心模块2.1.2…

frp实现内网穿透(多端口穿透)

frp实现内网穿透 准备一个公网服务器(腾讯、阿里、华为的云服务器) 下载frp的安装包 下载对应系统的安装包,不要下错文件。 注意amd对应x86架构的系统 arm对应 arm架构系统(macos) 点击下载 查看文档将对应的安装包放…

医保支付方式探索——利益共享机制的文章分析

Care-coordination: Gain-sharing Agreements in Bundled Payment Models 分析一下这篇文章,这篇文章于2021年发表在POMS上,但是引用量没有那么高。这篇文章涉及到医疗捆绑支付,应该可以学习一下。 文章研究一个在一个以最小成本为目标的质…

ASP.NET版本WOL服务的使用

本文以WOL为例,演示如何通过 GPT-4 让其为 WebAPI 项目设计一个网页。其中介绍了如何让GPT4生成相关功能,添加动画效果,接口鉴权等。 1. 背景 前面我们已经完成了一个WOL服务的开发,并将其迁移改造为了 ASP.NET 服务并完成了部署…

Java的TPC通信

TPC通信-快速入门 TPC通信-客户端开发 TPC通信-服务端开发 TPC通信-多发多收 客户端 服务端 TPC通信-支持与多个客户端同时通信 服务端 独立线程对象

禁止谷歌浏览器自动更新

禁止谷歌浏览器自动更新 在使用Python包selenium的时候浏览器版版本发生变化后产生很多问题如: 1、直接版本不对应无法运行 2、版本不一致导致debug启动浏览器超级慢 这里是已谷歌浏览器为代表的。 禁止自动更新的方法如下: 1、WinR调出运行&#x…

深度学习与深度迁移学习有什么区别?

深度学习包含深度迁移学习,它们都利用了深层神经网络(Deep Neural Network,DNN)来处理数据,并从中学习特征。但是,它们也有一些区别。 深度学习是一种机器学习方法,它通过多层神经网络来自动学…

Ext4文件系统解析(三)

1、前言 前文已经讲述了如何根据索引号获取实际的文件内容。对于文件而言,到了这里已经结束了。 但是对于文件夹来说,我们还需要从数据块中解析出对应的数据。 而在文件系统的实现中,文件夹的实际存储方式有着两种不同的实现,经典…