如何實現(xiàn)在純Web端完成各類API調試?
在軟件開發(fā)過程中,對于各類 API 的調試工作至關重要。API 調試是驗證和測試應用程序接口的有效性和正確性的關鍵步驟。傳統(tǒng)的 API 調試方法通常依賴于獨立的工具或桌面應用程序,限制了調試過程的靈活性和效率。
為推動 API 調試向更便捷、高效的方向發(fā)展,越來越多的開發(fā)人員開始尋求在純 Web 端完成各類 API 調試的解決方案。純 Web 端的 API 調試具有許多優(yōu)勢,包括無需安裝額外軟件、跨平臺支持、便于團隊協(xié)作等。本文將以開源項目 AREX 為例為大家介紹如何在 Web 端實現(xiàn)對各類 API 的調試功能。
AREX (http://arextest.com/)是一款開源的基于真實請求與數(shù)據(jù)的自動化回歸測試平臺,利用 Java Agent 技術與比對技術,通過流量錄制回放能力實現(xiàn)快速有效的回歸測試。同時提供了接口測試、接口比對測試等豐富的自動化測試功能。
難點一:跨域限制
要想在純 Web 端實現(xiàn)各類 API 的調試工作,首先要解決的難題是處理瀏覽器的跨域限制。
什么是跨域
瀏覽器跨域問題是指在 Web 開發(fā)中,當使用 JavaScript 代碼從一個域名的網(wǎng)頁訪問另一個域名的資源時會遇到的限制。瀏覽器實施了一種安全策略,稱為同源策略(Same-Origin Policy), 用于保護用戶信息的安全。同源策略要求網(wǎng)頁中的 JavaScript 只能訪問與其來源(協(xié)議、域名和端口號)相同的資源,而對于不同域名的資源訪問會受到限制。
由于瀏覽器存在跨域限制,我們不能在瀏覽器端隨心所欲地發(fā)送 HTTP 請求,這是瀏覽器的安全策略決定的。
解決方案
經(jīng)調研,突破此限制的方法有兩種:分別是 Chrome 插件代理和服務端代理,以下是兩種方法的比較。
權衡下來 AREX 選擇了 Chrome 插件代理的方法,其原理是利用了 Chrome 插件中 background 可以發(fā)送跨域請求的能力,我們將瀏覽器端攔截到的請求通過 window.postmassage 與 Chrome 插件的 background 進行通信(其中通信還需要 Chrome 插件的 content-script 作為數(shù)據(jù)橋梁)。
具體實現(xiàn)如下:
在頁面腳本中
生成一個隨機的字符串,并將其轉換為字符串形式,存儲在 tid 變量中。
使用 window.postMessage() 方法發(fā)送一條消息到其他擴展程序,消息包括一個類型為 `AREX_EXTENSION_REQUEST` 的標識、tid、以及 params 參數(shù)。
添加一個 message 事件監(jiān)聽器 receiveMessage,用于接收其他擴展程序發(fā)送的消息。
在 receiveMessage 函數(shù)中,檢查接收到的消息是否為類型為 AREX_EXTENSION_RES,并且 tid 與之前發(fā)送的消息的tid 相匹配。如果匹配成功,則移除事件監(jiān)聽器。
在內容腳本中
在后臺腳本中
難點二:API 調試
上述已經(jīng)解決了跨域問題,接下來就是如何實現(xiàn) API 調試的功能。
解決方案
Postman 是業(yè)內成熟的 API 調試工具,我們站在了 Postman 這位巨人的肩膀上,在 AREX 中引入了 Postman 的 JavaScript 沙盒,使用它的沙盒運行前置腳本、后置腳本以及斷言來調試 API。
以下是 AREX 請求的流程圖:
當點擊發(fā)送請求的時候,會將表單中的數(shù)據(jù)匯聚到一起,數(shù)據(jù)結構為:
這是 AREX 的數(shù)據(jù)結構,我們會將其轉換成 Postman 的數(shù)據(jù)結構。之后調用 PostmanRuntime.Runner() 方法,將轉換好了的 Postman 數(shù)據(jù)結構和當前所選的環(huán)境變量傳入,Runner 會執(zhí)行 preRequestScript 和 testScript 腳本。`preRequestScript` 發(fā)生在請求之前,可以在其中穿插請求以及對請求參數(shù)、環(huán)境變量進行操作,`testScript` 發(fā)生在請求之后,可以對 response 返回數(shù)據(jù)進行斷言操作,并且腳本中也可以通過 `console.log` 輸出數(shù)據(jù),在控制臺進行調試。
在 Postman 沙盒中也存在跨域問題,由于 Postman 沙盒的集成度非常高,為了確保與 PostmanRuntime 的同步以及方便性,我們采用了 Ajax 攔截技術。通過在瀏覽器端攔截 Ajax 請求,我們可以對請求進行修改、添加自定義邏輯或者進行其他處理操作。這樣可以實現(xiàn)對請求和響應的全局控制和定制化。
當 Postman 沙盒發(fā)送請求時,會攜帶一個名為 "postman-token" 的請求頭。我們攔截到這個 Ajax 請求后,會將請求參數(shù)進行拼裝,并通過 window.postMessage 發(fā)送給瀏覽器插件。瀏覽器插件再次構建 fetch 請求,將數(shù)據(jù)返回給 Postman 沙盒,使其輸出最終結果,包括響應(response)、測試結果(testResult)和控制臺日志(console.log)。需要注意的是,responseType 必須指定為 arraybuffer。
具體流程如下:
使用 xspy.onRequest() 方法注冊一個請求處理程序。這個處理程序接受兩個參數(shù):request 和 sendResponse。request 參數(shù)包含請求的相關信息,例如方法、URL、頭部、請求體等。sendResponse 是一個回調函數(shù),用于發(fā)送響應給請求方。
在處理程序中,通過檢查請求的頭部中是否存在 postman-token 來判斷請求是否來自 Postman。
如果存在該頭部,表示請求是通過 Postman 發(fā)送的。則使用 AgentAxios 發(fā)起一個新的請求,使用原始請求的方法、URL、頭部和請求體。AgentAxios 返回一個 agentData 對象,其中包含了響應的狀態(tài)碼、頭部和數(shù)據(jù)等信息。創(chuàng)建一個名為 dummyResponse 的響應對象,包含了與原始請求相關的信息。dummyResponse 的 status 字段為 agentData 的狀態(tài)碼,headers 字段為將 agentData 的頭部數(shù)組轉換為對象格式的結果,ajaxType 字段為字符串 xhr,responseType 字段為字符串 arraybuffer,response 字段為將 agentData 的數(shù)據(jù)轉換為 JSON 字符串并用 Buffer 包裝的結果。最后,使用 sendResponse(dummyResponse) 將響應發(fā)送給請求方。
如果請求不是來自 Postman,則直接調用 sendResponse(),表示不返回任何響應。
難點三:二進制對象序列化傳遞
還有一點值得一提,對于 `x-www-form-urlencoded` 和 `Raw` 類型的請求,由于它們都是普通的 JSON 對象,處理起來比較容易。但是對于 `form-data` 和 `binary` 類型的請求,需要支持傳輸二進制文件負載。然而,Chrome 插件的 `postMessage` 通信方式不支持直接傳遞二進制對象,導致無法直接處理這兩種類型的請求。
解決方案
為了解決這個問題,AREX 采用了 base64 編碼技術。在用戶選擇文件時,AREX 會將二進制文件轉換為 base64 字符串,然后進行傳輸。在 Chrome 插件端,AREX 會將 base64 數(shù)據(jù)進行解碼,并用于構建實際的 `fetch` 請求。這樣可以繞過直接傳遞二進制對象的限制。
就這個問題我們采用了 base64 編碼技術,在選擇文件時我們會將二進制文件轉換成 base64 字符串,再進行傳輸,Chrome 插件端會將 base64 數(shù)據(jù)解碼并用于構建實際的 `fetch` 請求。
這個流程圖描述了將 FormData 中的二進制文件轉換為 Base64 字符串,并通過 Chrome 插件代理將其轉換回文件并進行進一步處理的過程。
form-data binary(A):表示一個包含二進制文件的 FormData 表單數(shù)據(jù)。
FileReader(B):使用 FileReader 對象來讀取二進制文件。
readAsDataURL base64 string:FileReader 使用 readAsDataURL 方法將二進制文件讀取為 Base64 字符串。
Chrome 插件代理(C):Base64 字符串經(jīng)過讀取操作后,傳遞給 Chrome 插件代理進行進一步處理。
base64 string:表示經(jīng)過 FileReader 讀取二進制文件后得到的 Base64 字符串。
Uint8Array(D):在 Chrome 插件代理中,將 Base64 字符串轉換為 Uint8Array。
File(E):使用 Uint8Array 的數(shù)據(jù)創(chuàng)建一個新的 File 對象。
fetch(F):將新創(chuàng)建的 File 對象通過 fetch 方法或其他方式進行進一步處理,例如上傳到服務器或進行其他操作。
代碼分析
以下是代碼層面的分析:
toBase64 函數(shù)接受一個 File 對象作為參數(shù),并返回一個 Promise 對象,該 Promise 對象將解析為表示文件的 Base64 字符串。
在函數(shù)內部,創(chuàng)建了一個 FileReader 對象。通過調用 reader.readAsDataURL(file) 將文件讀取為 Data URL。當讀取操作完成時,通過 reader.onload 事件處理程序將讀取結果解析為字符串,并使用 resolve 將其傳遞給 Promise。如果發(fā)生錯誤,將使用 reject 將錯誤傳遞給 Promise。base64ToFile 函數(shù)接受兩個參數(shù):dataurl(Base64 字符串)和 filename(文件名),并返回一個 File 對象。
首先,將 dataurl 使用逗號分割成數(shù)組 arr,如果分割結果為空,則將其設為包含一個空字符串的數(shù)組。通過正則表達式匹配 arr[0] 中的內容,提取出 MIME 類型,即數(shù)據(jù)的類型。
使用 atob 將 Base64 字符串解碼為二進制字符串 bstr。創(chuàng)建一個長度為 n 的 Uint8Array 數(shù)組 u8arr。使用循環(huán)遍歷 bstr,將每個字符的 Unicode 編碼放入 u8arr 中。
最后,使用 File 構造函數(shù)創(chuàng)建并返回一個新的 File 對象,其中包含了從 u8arr 中讀取的文件數(shù)據(jù)、文件名和 MIME 類型。導出 base64ToFile 函數(shù),以便在其他地方使用。
以上就是如何實現(xiàn)在純Web端完成各類API調試?的詳細內容,更多關于web調用api接口實例的資料請關注腳本之家其它相關文章!
你可能感興趣的文章
-
Web3無助記詞錢包:安全性和便捷度的取舍
這篇文章主要介紹了Web3無助記詞錢包:安全性和便捷度的取舍的相關資料,需要的朋友可以參考下本文纖細內容介紹…
2023-05-23 -
Web3錢包的未來:創(chuàng)新、挑戰(zhàn)以及重要問題
這篇文章主要介紹了Web3錢包的未來:創(chuàng)新、挑戰(zhàn)以及重要問題的相關資料,需要的朋友可以參考下本文詳細內容介紹…
2023-05-19 -
Web3中的DAO是什么?Web3和DAO如何改變生產(chǎn)關系?
這篇文章主要介紹了Web3中的DAO是什么?Web3和DAO如何改變生產(chǎn)關系?的相關資料,需要的朋友可以參考下本文詳細內容介紹…
2023-05-16 -
一文分析為什么Web3需要數(shù)字身份?
這篇文章主要介紹了一文分析為什么Web3需要數(shù)字身份?的相關資料,需要的朋友可以參考下本文詳細內容介紹…
2023-04-26 -
Web3.0時代是一個什么時代?有哪些主要特征?
這篇文章主要介紹了Web3.0時代是一個什么時代?有哪些主要特征?的相關資料,需要的朋友可以參考下本文詳細內容介紹…
2023-04-19 -
web2與web3有什么區(qū)別?一文了解web2與web3的區(qū)別
這篇文章主要介紹了web2與web3有什么區(qū)別?一文了解web2與web3的區(qū)別的相關資料,需要的朋友可以參考下本文詳細內容介紹…
2023-03-29 -
Web3睡覺Sleepagotchi 收集NFT還收獲健康睡眠
這篇文章主要介紹了Web3睡覺Sleepagotchi 收集NFT還收獲健康睡眠的相關資料,需要的朋友可以參考下本文詳細內容介紹…
2023-03-20 -
Web3域名統(tǒng)治者:一文全覽ENS現(xiàn)狀與前景
正如以太坊在智能合約平臺領域的絕對主導地位,ENS 在 Web3 域名領域的地位也難以被撼動?!?/p> 2023-03-20
-
Web3.0的發(fā)展趨勢是什么?2023年Web3.0的五大發(fā)展趨勢
這篇文章主要介紹了Web3.0的發(fā)展趨勢是什么?2023年Web3.0的五大發(fā)展趨勢的相關資料,需要的朋友可以參考下本文詳細內容介紹…
2023-03-09 -
常用web3錢包有哪些軟件?常用web3錢包盤點
這篇文章主要介紹了常用web3錢包有哪些軟件?常用web3錢包盤點的相關資料,需要的朋友可以參考下本文詳細內容介紹…
2023-03-03