加入收藏 | 设为首页 | 会员中心 | 我要投稿 PHP编程网 - 黄冈站长网 (http://www.0713zz.com/)- 数据应用、建站、人体识别、智能机器人、语音技术!
当前位置: 首页 > 运营中心 > 网站设计 > 教程 > 正文

基于HTTP请求拦截,快速解决跨域和代理Mock

发布时间:2019-03-03 07:29:26 所属栏目:教程 来源:邓仲哲
导读:副标题#e# 近几年,随着 Web 开发逐渐成熟,前后端分离的架构设计越来越被众多开发者认可,使得前端和后端可以专注各自的职能,降低沟通成本,提高开发效率。 在前后端分离的开发模式下,前端和后端工程师得以并行工作。当遇到前端界面展示需要的数据,而后
副标题[/!--empirenews.page--]

近几年,随着 Web 开发逐渐成熟,前后端分离的架构设计越来越被众多开发者认可,使得前端和后端可以专注各自的职能,降低沟通成本,提高开发效率。

在前后端分离的开发模式下,前端和后端工程师得以并行工作。当遇到前端界面展示需要的数据,而后端对应的接口还没有完成开发的情况时,需要一个数据源来保证前端工作的顺利进行。

今天这篇文章,我们会介绍几种常见的方法和其中存在的问题,并提出如何基于HTTP 请求拦截,快速解决跨域和代理 mock 问题的方案。

常见方法及问题

请求 mock 服务器

最常规的做法是维护一个提供静态数据的 mock 服务器(它提供的数据称为 mock 数据),前端请求 mock 服务器获取数据即可,但这种静态数据维护不便。

请求 AMP

更好的做法是有一个根据接口定义来自动生成数据的 mock 服务器,我们称为AMP(接口管理平台,API Manage Platform),前端请求该服务器获取数据。

在这种场景下,如果有些接口已经完成开发,前端需要手动修改代码去设置不同接口的请求地址。当接口数量较多时,这种方法会变得非常低效。因此, AMP 一般也会同时提供代理功能,也就是指前端仍请求 AMP,AMP 会根据接口完成情况来决定返回 mock 数据,还是将请求再次代理到真实的业务服务器获取数据后返回。

但是这种方案的问题在于当涉及到需要角色权限验证的接口时,登录输入用户信息后在浏览器中会缓存 cookie,当访问与登录时同域名的接口时,浏览器会自动携带 cookie,由服务器解析 cookie 并鉴权后获取对应权限的接口数据。前端一般是在本地启动服务器进行开发,当业务服务器的接口完成开发,这时再采用请求 AMP 的方法切换接口数据,就会出现跨域的情况。

由于浏览器的安全机制决定跨域访问时无法携带 cookie,并且无法通过代码读取 cookie,因此通过代码传递 cookie 跨域不可行,而现有的解决方案也不完美:

  • 如果在 AMP 额外增加模拟登陆的功能,会因为所有接口的权限固定不变,无法适配一个接口对不同角色有不同权限而返回相应的数据;而且一旦鉴权的接口功能变更、失效等情况发生,都需要重写修改 AMP 的代理功能,代价较大。
  • 如果利用浏览器插件保存登陆信息、提供代理,则需要兼容不同浏览器,成本太高。

针对上述技术问题,本文提出了一种可跨浏览器,并在前端实现的不侵入业务代码的代理方法。

基于 HTTP 请求拦截 实现前端接口代理

基于 HTTP 请求拦截实现前端接口的方式,从更底层的角度实现了接口开发完成前后的 mock 数据,及业务服务器真实数据之间的切换,并且解决了现有技术中由 HTTP 请求通过 AMP 代理到业务服务器产生跨域无法携带权限信息,导致无法按照角色权限返回请求数据的技术问题。

主要创新点

  • 在更底层基于 XMLHttpRequest 和 Fetch API 实现拦截代理,不需要考虑主流浏览器类型,和 JavaScript 依赖的工具库;
  • 在前端实现代理,保留了登陆信息,无需额外处理鉴权问题;
  • 提供一种可以快速实现且可插拔的使用方式。

总的来说,这个方案提供了一种可快速实现,运行在前端浏览器中,且不依赖浏览器类型的请求代理方法。

设计思路

Web 前端开发一般使用 JavaScript 语言,浏览器环境的 HTTP 请求都是基于 Fetch API 或 XMLHttpRequest API 来实现的(基于前者的请求记做 xhr,后者记做 fetch),主流的 Javascript 开源工具库如 Axios、Request 也是这样。所以,我们的方案就是要通过在底层拦截 xhr 或 fetch,根据一定的判断逻辑来实现前端代理功能。

实现方式

首先,重新封装浏览器环境中原生的 XMLHttpRequest API 和 Fetch API。基本思路是将这两个原生的 API 保存起来,添加到各自重新封装的同名 API 中(记作新 API),为新 API 写入与原生 API 中同名的方法和属性,在携带请求参数的同名方法(比如下文中的 open 和 send)里加入拦截请求和代理的逻辑 ApiProxy,对外开放一个可配置该拦截逻辑的接口,用于配置针对不同的 HTTP 请求格式所请求数据的拦截和代理逻辑。

基于HTTP请求拦截,快速解决跨域和代理Mock

图1:代理与AMP和终端业务的交互流程

ApiProxy 在这个过程中的主要作用和工作流程可以归纳为:

  1. 注册拦截器。接收并拦截 HTTP 请求,解析该请求中的参数,这里的参数是指能在 AMP 中唯一标识该接口的参数,比如域名+请求方法(如 GET、POST 等)+路径(如 https://service.com/user 中的/user)。
  2. 根据该参数生成发送 AMP 的请求。AMP 实时维护了 mock 服务器上存储的接口以及业务服务器上存储的真实接口的相关信息,包括接口的定义、域名、属性、开发状态等。
  3. AMP 根据请求查询接口定义数据,如果接口存在且状态是开发中,则返回根据接口定义生成的 mock 数据,否则返回特定响应标志,如图 1 中的「{code:』200302』}」。
  4. Apiproxy 收到 AMP 的响应后判断是否有特殊标志,没有直接返回 mock 数据到原请求,有则表示后端接口开发完成,继续发送原 HTTP 请求到后端服务器请求后端服务器存储的真实数据,相当于没有对原请求做任何处理。

和传统的将 HTTP 请求发送给 AMP 不同的是 ,AMP 根据接口状态判断是根据请求直接返回 mock 数据,还是开启代理将 HTTP 请求再发送给业务服务器(此时跨域访问会丢失原始 HTTP 请求中浏览器携带的 cookie),不直接将 HTTP 请求发送给 AMP,而是对请求正式发出之前进行拦截,并解析其中的参数发送给 AMP,由 AMP 反馈接口状态,若开发完成则将 HTTP 请求正式发送给业务服务器。因为没有修改该请求,只是延迟发送,这样就保持了原请求与业务服务器之间的所有鉴权等相关信息,由此解决了跨域访问无法携带 cookie 的问题。

不同请求方式下 ApiProxy 的实现

由于不同请求方式的底层设计不同,我们相应的具体封装手段也不同。

基于HTTP请求拦截,快速解决跨域和代理Mock

图2:代理核心工作原理

XMLHttpRequest

(编辑:PHP编程网 - 黄冈站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读