這是 Jerry 2021 年的第 64 篇文章,也是汪子熙公衆号總共第 341 篇原創文章。
Jerry 的前一篇文章 紀念特洛伊英雄 Sinon - SAP UI5 Mock Server 使用步驟和工作原理介紹,提到了 SAP UI5 Mock Server,能夠在幕後将浏覽器原生的 XMLHttpRequest API,替換成基于 Sinon.js 實作的 FakeXMLHttpRequest,進而實作為所有 OData 相關的請求,傳回事先準備好的 Mock 資料之目的。

文末提到了攔截器 HTTP Interceptor 的概念。在 HTTP 攔截器的工作場景中,HTTP 請求在兩個時間點内,可以被架構或者應用開發人員編寫的攔截器處理:
程式代碼調用 API 發送 HTTP 請求後,在 HTTP 請求實際從浏覽器發出之前,由攔截器進行預處理
應用程式得到遠端的伺服器響應後,在交給其回調函數處理之前,由攔截器進行預處理
本文介紹一個使用攔截器的實際例子。
我們知道 SAP UI5 打開調試模式後,在 Console 控制台會看到很多額外的來自 SAP UI5 架構代碼的 log 輸出。
Jerry 曾經在 SAP 社群上寫過一篇部落格,羅列出了我在 SAP CRM Fiori 開發團隊工作時,通過單步調試的方式解決的一些 bug:
My UI5 debugging tips and experience collection – how to resolve UI5 issues through debugging by yourself
文章裡提到的不少例子,我都在 SAP UI5 架構代碼裡加上了一些額外的 console.log, 然後觀察其運作時列印出的内容。這種方法能幫助我在排除錯誤和學習 SAP UI5 架構實作原理時,更好地了解其執行細節。
比如文章 深入學習SAP UI5架構代碼系列之八:談談 SAP UI5 的視圖控件 ID,以及其和 Angular 視圖的異同 裡介紹了 SAP UI5 控件 ID 的生成邏輯:
如果開發人員顯式指定了控件 ID,則使用該 ID 生成 HTML 原生标簽
如果開發人員沒有指定控件 ID,則使用控件中繼資料裡包含的字首,加上全局計數器自動生成 ID
假設我們想直接在 Chrome 開發者工具 Sources 面闆裡如上圖所示的 SAP UI5 架構檔案 ManagedObject-dbg.js 裡,添加一行 console.log 語句列印出控件 ID:
儲存之後,我們會看到該檔案左邊有一個小的黃色驚歎号圖示,以及一行警告消息:
Changes to this file were not saved to file system.
一旦重新整理浏覽器,之前對 ManagedObject-dbg.js 的修改就丢失了。
原來,Chrome 開發者工具的 Sources 面闆,提供了一個簡易的 Workspace(工作區)功能。
我們可以點選上圖的加号按鈕,将某個本地檔案夾添加到 Chrome 開發者工具的工作區中去。接下來,在該本地檔案夾内啟動 Web 應用,就能在 Chrome 開發者工具 Sources 标簽内,看到加載的檔案。更妙的是,此時我們直接在 Chrome 開發者工具裡編輯加載的檔案,修改會自動同步到本地檔案中去。
例如,我把名為 walkthrough 的本地檔案夾添加到 Chrome 開發者工具的工作區内:
接下來,我在 Chrome 開發者工具裡直接編輯該檔案夾下的 index.html, 儲存。然後重新重新整理浏覽器,發現之前的修改已經被持久化到本地的 index.html 檔案裡去了,同時在 Chrome 開發者工具裡被修改的檔案左邊,有一個綠色的圓點作為提示。
在回到之前試圖修改的 SAP UI5 架構檔案 ManagedObject-dbg.js. 因為我是通過遠端加載的方式,從 openui5.hana.ondemand.com 伺服器導入 SAP UI5 庫檔案,是以本地并未存儲 SAP UI5 架構檔案,是以無法使用 Chrome 開發者工具的工作區映射功能。
此時 HTTP 攔截器就派上用場了。使用攔截器,将浏覽器加載 ManagedObject-dbg.js 的請求攔截下來,傳回另一個我們事先準備好的加上了 console.log 語句的 JS 檔案即可。
這裡我使用的攔截器軟體是 Fiddle,一個網絡抓包工具,可以将網絡傳輸發送與接受的資料包執行截獲,編輯,轉存,重發等操作。用來實作本文描述的檔案請求攔截場景,更是殺雞用牛刀,小菜一碟。
打開 Fiddle,在監控的網絡請求裡,找到并選中對 ManagedObject-dbg.js 的請求,打開右側的 AutoResponder 面闆:
勾上 “Enable rules” 之前的 checkbox,維護一條規則,其語義為:如果 Fiddle 檢測到一條請求的 url 為規則指定的值,則傳回一個事先準備好的,包含了 console.log 的同名本地檔案:
重新整理浏覽器,如今在 Fiddle 面闆裡能觀察到,當請求檔案 ManagedObject-dbg.js 時,傳回的響應裡,确實包含了我們手動添加的 console.log 語句,說明規則執行成功。
然而在 Console 面闆裡,發現一條和跨域通路相關的錯誤消息:
Access to XMLHttpRequest has been blocked by CORS policy: No Access-Control-Allow-Origin header is present on the requested resource.
在 Chrome 開發者工具 Network 标簽頁裡檢視該請求的響應頭部字段,發現果然缺少 Access-Control-Allow-Origin 字段:
Ctrl + R 打開 Fiddle 的自定義規則編輯器:
使用腳本,将缺失的 Access-Control-Allow-Origin 字段添加到響應頭部即可:
之後,我們能在 Chrome 開發者工具裡看到期望中的被 Fiddle 自定義規則編輯器所添加到 HTTP 響應的頭部字段:
為了讓我們自定義的 console.log 顯示的内容不至于淹沒在海量的 SAP UI5 架構日志裡,我們可以利用 console.log 函數的第二個格式參數,讓我們的列印輸出變得醒目一些:
關于該參數的詳細用法,請參考我的部落格:
Chrome Development Tool tips used in my daily work
希望本文能幫助大家對 Web 開發利器之一,Fiddle 軟體的使用有一個直覺的感受,感謝閱讀。