SAP UI5 應用的 OData 後設資料請求的傳送原理分析

注销發表於2022-02-16

當我們的 SAP UI5 應用裡使用了 OData 模型從遠端伺服器讀取資料,具體實現細節可以參考我這篇文章:SAP UI5 初學者教程之二十四 - 如何使用 OData 資料模型,可以在 Chrome 開發者工具裡,觀察到一個由 SAP UI5 框架自動發出的後設資料請求。

請求的 url :

https://services.odata.org/V2...$metadata?sap-language=EN

該請求沒有 content-type 欄位,只有一個 accept 欄位,值為:application/xml

還有一個 MaxDataServiceVersion,值為 3.0

響應的頭部欄位裡,沒有 Accept 欄位,只有 Content-Type 欄位,注意大小寫:

具體發起該 HTTP 請求的程式碼位置:ODataMetadata 的 _loadMetadata 方法:

在建構函式里觸發 _loadMetadata:

基於 url 建立 request 物件:

根據如下的 API 獲得 HTTP 請求支援的語言:Accept-Language

sap.ui.getCore().getConfiguration().getLanguageTag()

計算出來是:en-US

bAsync 標誌位為 true,代表這是個非同步請求:

withCredentials 標誌位為 false:

然後使用傳統的 promise API 發起請求:

如果 metadata 載入成功,就在其回撥裡執行初始化邏輯:

if (!this.oMetadata.isLoaded()) {
                this.oMetadata.attachFailed(this.onMetadataFailed);
            }

下面呼叫 OData API,傳入剛才構造好的請求物件,進行請求傳送:

進入 datajs.js, 首先 prepareRequest:

normalizeHeaders:對頭部欄位進行規範化處理,其實就是將頭部欄位轉換成小寫:

然後呼叫 invokeRequest 進行傳送:

移交給 httpClient:

datajs.js 的底層還是基於 XHR 即 XmlHttpRequest:

直接使用瀏覽器原生的 XMLHttpRequest:

這裡的 fallback 機制用的是已經很古老的 ActiveXObject 了,現代瀏覽器都不會執行到:

var createXmlHttpRequest = function () {
        /// <summary>Creates a XmlHttpRequest object.</summary>
        /// <returns type="XmlHttpRequest">XmlHttpRequest object.</returns>
        if (window.XMLHttpRequest) {
            return new window.XMLHttpRequest();
        }
        var exception;
        if (window.ActiveXObject) {
            try {
                return new window.ActiveXObject("Msxml2.XMLHTTP.6.0");
            } catch (_) {
                try {
                    return new window.ActiveXObject("Msxml2.XMLHTTP.3.0");
                } catch (e) {
                    exception = e;
                }
            }
        } else {
            exception = { message: "XMLHttpRequest not supported" };
        }
        throw exception;
    };

最後呼叫 xhr.open:

使用 send api 進行請求傳送。

更多Jerry的原創文章,盡在:"汪子熙":

相關文章