如何实现在纯Web端完成各类API调试?

时间:2024-11-04  分类:电子


在软件开发过程中,对于各类API的调试工作至关重要。API调试是验证和测试应用程序接口的有效性和正确性的关键步骤。传统的API调试方法通常依赖于独立的工具或桌面应用程序,限制了调试过程的灵活性和效率。


为推动API调试向更便捷、高效的方向发展,越来越多的开发人员开始寻求在纯Web端完成各类API调试的解决方案。纯Web端的API调试具有许多优势,包括无需安装额外软件、跨平台支持、便于团队协作等。本文将以开源项目AREX为例为大家介绍如何在Web端实现对各类API的调试功能。


AREX(http://arextest.net/)是一款开源的基于真实请求与数据的自动化回归测试平台,利用JavaAgent技术与比对技术,通过流量录制回放能力实现快速有效的回归测试。同时提供了接口测试、接口比对测试等丰富的自动化测试功能。


难点一:跨域限制


要想在纯Web端实现各类API的调试工作,首先要解决的难题是处理浏览器的跨域限制。


什么是跨域


浏览器跨域问题是指在Web开发中,当使用JavaScript代码从一个域名的网页访问另一个域名的资源时会遇到的限制。浏览器实施了一种安全策略,称为同源策略(Same-OriginPolicy),用于保护用户信息的安全。同源策略要求网页中的JavaScript只能访问与其来源(协议、域名和端口号)相同的资源,而对于不同域名的资源访问会受到限制。


由于浏览器存在跨域限制,我们不能在浏览器端随心所欲地发送HTTP请求,这是浏览器的安全策略决定的。


解决方案


经调研,突破此限制的方法有两种:分别是Chrome插件代理和服务端代理,以下是两种方法的比较。


权衡下来AREX选择了Chrome插件代理的方法,其原理是利用了Chrome插件中background可以发送跨域请求的能力,我们将浏览器端拦截到的请求通过window.postmassage与Chrome插件的background进行通信(其中通信还需要Chrome插件的content-script作为数据桥梁)。


具体实现如下:


在页面脚本中


生成一个随机的字符串,并将其转换为字符串形式,存储在tid变量中。


使用window.postMessage()方法发送一条消息到其他扩展程序,消息包括一个类型为`AREX_EXTENSION_REQUEST`的标识、tid、以及params参数。


添加一个message事件监听器receiveMessage,用于接收其他扩展程序发送的消息。


在receiveMessage函数中,检查接收到的消息是否为类型为AREX_EXTENSION_RES,并且tid与之前发送的消息的tid相匹配。如果匹配成功,则移除事件监听器。


在内容脚本中


在后台脚本中


难点二:API调试


上述已经解决了跨域问题,接下来就是如何实现API调试的功能。


解决方案


Postman是业内成熟的API调试工具,我们站在了Postman这位巨人的肩膀上,在AREX中引入了Postman的JavaScript沙盒,使用它的沙盒运行前置脚本、后置脚本以及断言来调试API。


以下是AREX请求的流程图:


当点击发送请求的时候,会将表单中的数据汇聚到一起,数据结构为:


这是AREX的数据结构,我们会将其转换成Postman的数据结构。之后调用PostmanRuntime.Runner()方法,将转换好了的Postman数据结构和当前所选的环境变量传入,Runner会执行preRequestScript和testScript脚本。`preRequestScript`发生在请求之前,可以在其中穿插请求以及对请求参数、环境变量进行操作,`testScript`发生在请求之后,可以对response返回数据进行断言操作,并且脚本中也可以通过`console.log`输出数据,在控制台进行调试。


在Postman沙盒中也存在跨域问题,由于Postman沙盒的集成度非常高,为了确保与PostmanRuntime的同步以及方便性,我们采用了Ajax拦截技术。通过在浏览器端拦截Ajax请求,我们可以对请求进行修改、添加自定义逻辑或者进行其他处理操作。这样可以实现对请求和响应的全局控制和定制化。


当Postman沙盒发送请求时,会携带一个名为postman-token的请求头。我们拦截到这个Ajax请求后,会将请求参数进行拼装,并通过window.postMessage发送给浏览器插件。浏览器插件再次构建fetch请求,将数据返回给Postman沙盒,使其输出最终结果,包括响应(response)、测试结果(testResult)和控制台日志(console.log)。需要注意的是,responseType必须指定为arraybuffer。


具体流程如下:


使用xspy.onRequest()方法注册一个请求处理程序。这个处理程序接受两个参数:request和sendResponse。request参数包含请求的相关信息,例如方法、URL、头部、请求体等。sendResponse是一个回调函数,用于发送响应给请求方。


在处理程序中,通过检查请求的头部中是否存在postman-token来判断请求是否来自Postman。


如果存在该头部,表示请求是通过Postman发送的。则使用AgentAxios发起一个新的请求,使用原始请求的方法、URL、头部和请求体。AgentAxios返回一个agentData对象,其中包含了响应的状态码、头部和数据等信息。创建一个名为dummyResponse的响应对象,包含了与原始请求相关的信息。dummyResponse的status字段为agentData的状态码,headers字段为将agentData的头部数组转换为对象格式的结果,ajaxType字段为字符串xhr,responseType字段为字符串arraybuffer,response字段为将agentData的数据转换为JSON字符串并用Buffer包装的结果。最后,使用sendResponse(dummyResponse)将响应发送给请求方。


如果请求不是来自Postman,则直接调用sendResponse(),表示不返回任何响应。


难点三:二进制对象序列化传递


还有一点值得一提,对于`x-www-form-urlencoded`和`Raw`类型的请求,由于它们都是普通的JSON对象,处理起来比较容易。但是对于`form-data`和`binary`类型的请求,需要支持传输二进制文件负载。然而,Chrome插件的`postMessage`通信方式不支持直接传递二进制对象,导致无法直接处理这两种类型的请求。


解决方案


为了解决这个问题,AREX采用了base64编码技术。在用户选择文件时,AREX会将二进制文件转换为base64字符串,然后进行传输。在Chrome插件端,AREX会将base64数据进行解码,并用于构建实际的`fetch`请求。这样可以绕过直接传递二进制对象的限制。


就这个问题我们采用了base64编码技术,在选择文件时我们会将二进制文件转换成base64字符串,再进行传输,Chrome插件端会将base64数据解码并用于构建实际的`fetch`请求。


这个流程图描述了将FormData中的二进制文件转换为Base64字符串,并通过Chrome插件代理将其转换回文件并进行进一步处理的过程。


form-databinary(A):表示一个包含二进制文件的FormData表单数据。


FileReader(B):使用FileReader对象来读取二进制文件。


readAsDataURLbase64string:FileReader使用readAsDataURL方法将二进制文件读取为Base64字符串。


Chrome插件代理(C):Base64字符串经过读取操作后,传递给Chrome插件代理进行进一步处理。


base64string:表示经过FileReader读取二进制文件后得到的Base64字符串。


Uint8Array(D):在Chrome插件代理中,将Base64字符串转换为Uint8Array。


File(E):使用Uint8Array的数据创建一个新的File对象。


fetch(F):将新创建的File对象通过fetch方法或其他方式进行进一步处理,例如上传到服务器或进行其他操作。


代码分析


以下是代码层面的分析:


toBase64函数接受一个File对象作为参数,并返回一个Promise对象,该Promise对象将解析为表示文件的Base64字符串。


在函数内部,创建了一个FileReader对象。通过调用reader.readAsDataURL(file)将文件读取为DataURL。当读取操作完成时,通过reader.onload事件处理程序将读取结果解析为字符串,并使用resolve将其传递给Promise。如果发生错误,将使用reject将错误传递给Promise。base64ToFile函数接受两个参数:dataurl(Base64字符串)和filename(文件名),并返回一个File对象。


首先,将dataurl使用逗号分割成数组arr,如果分割结果为空,则将其设为包含一个空字符串的数组。通过正则表达式匹配arr[0]中的内容,提取出MIME类型,即数据的类型。


使用atob将Base64字符串解码为二进制字符串bstr。创建一个长度为n的Uint8Array数组u8arr。使用循环遍历bstr,将每个字符的Unicode编码放入u8arr中。


最后,使用File构造函数创建并返回一个新的File对象,其中包含了从u8arr中读取的文件数据、文件名和MIME类型。导出base64ToFile函数,以便在其他地方使用。


以上就是如何实现在纯Web端完成各类API调试?的全部内容,望能这篇如何实现在纯Web端完成各类API调试?可以帮助您解决问题,能够解决大家的实际问题是非常好学习网一直努力的方向和目标。