JavaScript 物件模型

本頁內容適用於 ApigeeApigee Hybrid

查看 Apigee Edge 說明文件。

本主題將說明 Apigee JavaScript 物件模型。如果您打算使用 JavaScript 政策,在 API Proxy 中新增自訂 JavaScript,請務必瞭解這個模型。

關於 JavaScript 物件模型

JavaScript 物件模型會定義物件和相關聯的屬性,這些屬性可供在 Apigee 代理程式流程中執行的 JavaScript 程式碼使用。使用 JavaScript 政策將這段自訂程式碼附加至 API Proxy 流程。

這個模型定義的物件在 API Proxy 流程中具有範圍,也就是說,只有在流程中的特定時間點,才能使用特定物件和屬性。執行 JavaScript 時,系統會為執行作業建立範圍。在該範圍內,系統會建立下列物件參照:

  • context提供訊息內容存取權的物件
  • request可存取要求物件的簡寫
  • response可存取回應物件的簡寫
  • crypto提供各種雜湊函式
  • print用於發出輸出內容的函式
  • 屬性允許讀取政策的設定屬性

背景資訊物件

context 物件具有全域範圍。您可以在 API Proxy 流程中的任何位置使用這項變數。它有四個子物件:proxyRequestproxyResponsetargetRequesttargetResponse。這些子物件的範圍限定於周遭要求和回應,也就是 Proxy 要求和回應,或是目標要求和回應。舉例來說,如果 JavaScript 政策在流程的 Proxy 端點部分執行,則 context.proxyRequestcontext.proxyResponse 物件會位於範圍內。如果 JavaScript 在目標流程中執行,則 context.targetRequestcontext.targetResponse 物件會位於範圍內。

context 物件也有屬性和方法,本主題會詳細說明。舉例來說,下列 JavaScript 程式碼範例會使用 context.flow 屬性,並在 context 上呼叫 get/setVariable() 方法。

if (context.flow=="PROXY_REQ_FLOW") {
     var username = context.getVariable("request.formparam.user");
     context.setVariable("USER.name", username);
}

這些方法會直接與流程變數互動。context.flow 屬性值是目前的流程範圍。在 Proxy 要求流程中,這會設為常數 PROXY_REQ_FLOW。如果目標回應流程設為 TARGET_RESP_FLOW,這個常數有助於執行範圍專屬的程式碼。getter 可讓您取得流程變數,setter 則可讓您設定流程變數。這些變數通常可在 Proxy 流程中使用,並供其他政策取用。

詳情和範例請參閱內容物件參考資料

加密物件

crypto 物件會在 JavaScript 物件模型中新增基本的高效能加密支援功能。詳情和範例請參閱 crypto 物件參考資料

要求和回應物件

requestresponse 物件是環境要求和回應的簡寫參照,可以是 Proxy 要求和回應,也可以是目標要求和回應。這些變數參照的物件取決於 JavaScript 政策的執行環境。如果 JavaScript 在 Proxy 端點的流程中執行,則要求和回應變數會參照 context.proxyRequestcontext.proxyResponse。如果 JavaScript 在目標流程中執行,則變數會參照 context.targetRequestcontext.targetResponse

JavaScript 物件模型包含 print() 函式,可用於將偵錯資訊輸出至 Apigee 偵錯工具。請參閱「使用 JavaScript print() 陳述式進行偵錯」。

屬性物件

在政策設定中使用 Properties 元素時,JavaScript 程式碼可使用 properties 變數存取這些屬性的值。

舉例來說,如果您的 JavaScript 設定包含:

<Javascript name='JS-1' >
  <Properties>
    <Property name="number">8675309</Property>
    <Property name="firstname">Jenny</Property>
  </Properties>
  <ResourceURL>jsc://my-code.js</ResourceURL>
</Javascript>

接著,您可以在 my-code.js 中執行下列操作:

  print(properties.firstname);  // prints Jenny
  print(properties.number);  // 8675309

更實際地說,設定可讓程式碼在不同環境、不同時間或因任何原因執行時,呈現不同行為。

舉例來說,下列程式碼指定了「變數名稱」,以及 JavaScript 應將資訊發布至的輸出內容樣式:

<Javascript name='JS-2' >
  <Properties>
    <Property name="output">my_output_variable</Property>
    <Property name="prettyPrint">true</Property>
  </Properties>
  <ResourceURL>jsc://emit-results.js</ResourceURL>
</Javascript>
接著,程式碼可以在 emit-results.js 中執行下列操作:
var result = { prop1: "something", prop2 : "something else" } ;
if (properties.prettyPrint == "true") {
  context.setVariable(properties.output, JSON.stringify(result, null, 2));
}
else {
  context.setVariable(properties.output, JSON.stringify(result));
}

加密物件參考資料

您可以使用 crypto 物件,在 JavaScript 中執行基本的加密雜湊函式。

crypto 物件具有全域範圍。您可以在 API Proxy 流程中的任何位置使用。您可以使用 Crypto 處理下列雜湊物件:

  • SHA-1
  • SHA256
  • SHA512
  • MD5

使用 SHA-1 物件

您可以建立 SHA-1 物件、更新物件,以及將物件轉換為十六進位和 Base64 值。

建立新的 SHA-1 物件

var _sha1 = crypto.getSHA1();

更新 SHA-1 物件

語法

_sha1.update(value);

參數

  • value - (字串) 任何字串值。

範例

更新 SHA-1 物件:

_sha1.update("salt_value");

_sha1.update("some text");

以十六進位字串形式傳回 SHA-1 物件

var _hashed_token = _sha1.digest();

以 Base64 字串形式傳回 SHA-1 物件

var _hashed_token = _sha1.digest64();

使用 SHA-256 物件

您可以建立 SHA-256 物件、更新物件,以及將物件轉換為十六進位和 Base64 值。

建立新的 SHA-256 物件

var _sha256 = crypto.getSHA256();

更新 SHA-256 物件

語法

_sha256.update(value);

參數

  • value - (字串) 任何字串值。

範例

更新 SHA-256 物件:

_sha256.update("salt_value");

_sha256.update("some text");

以十六進位字串形式傳回 SHA-256 物件

var _hashed_token = _sha256.digest();

以 base64 字串形式傳回 SHA-256 物件

var _hashed_token = _sha256.digest64();

使用 SHA-512 物件

您可以建立 SHA-512 物件、更新物件,以及將物件轉換為十六進位和 Base64 值。

建立新的 SHA-512 物件

var _sha512 = crypto.getSHA512();

更新 SHA-512 物件

語法

_sha512.update(value);

參數

  • value - (字串) 任何字串值。

範例

更新 SHA-512 物件:

_sha512.update("salt_value");

_sha512.update("some text");

以十六進位字串形式傳回 SHA-512 物件

var _hashed_token = _sha512.digest();

以 Base64 字串形式傳回 SHA-512 物件

var _hashed_token = _sha512.digest64();

使用 MD5 物件

您可以建立 MD5 物件、更新物件,以及將物件轉換為十六進位和 base64 值。

建立新的 MD5 物件

var _md5 = crypto.getMD5();

更新 MD5 物件

語法

_md5.update(value);

參數

  • value - (字串) 任何字串值。

範例

更新 MD5 物件:

_md5.update("salt_value");

_md5.update("some text");

以十六進位字串形式傳回 MD5 物件

var _hashed_token = _md5.digest();

以 Base64 字串形式傳回 MD5 物件

var _hashed_token = _md5.digest64();

支援加密日期/時間

crypto 物件支援日期/時間格式化模式。

crypto.dateFormat()

以字串格式傳回日期。

語法

crypto.dateFormat(format, [timezone], [time])

參數

  • format - (String) 這個參數的基礎實作是 java.text.SimpleDateFormat。例如:'YYYY-MM-DD HH:mm:ss.SSS'
  • timezone - (字串,選填) 這個參數的基礎實作項目為 java.util.TimeZone。 這個參數與預設值相同:世界標準時間
  • time - (數字,選用) 要設定格式的 Unix 時間戳記值。預設: 目前時間

範例

取得目前時間 (精確到毫秒):

var _now = crypto.dateFormat('YYYY-MM-DD HH:mm:ss.SSS');

取得太平洋時區的目前時間:

var _pst = crypto.dateFormat('YYYY-MM-DD HH:mm:ss.SSS','PST');

取得十秒後的值:

var _timeNow = Number(context.getVariable('system.timestamp'));
var tenSeconds = crypto.dateFormat('YYYY-MM-DD HH:mm:ss.SSS','PST', _timeNow + 10 * 1000);

其他範例。另請參閱 java.text.SimpleDateFormat 說明文件。

var _pst = crypto.dateFormat('M');
var _pst = crypto.dateFormat('EEE, d MMM yyyy HH:mm:ss Z');
var _pst = crypto.dateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");

使用 WS-Security 和 X.509 憑證保護 SOAP 文件

使用 WS-Security 和 RSA/X.509 數位簽章保護 SOAP 文件。

crypto.wsSecRsaSign()

簽署 SOAP 文件,並傳回已簽署的酬載。

語法

crypto.wsSecRsaSign(payload, options)

參數

  • payload - (String) 要簽署的 SOAP 文件。
  • options - (物件) 數位簽章的設定選項。下表列出可用的設定選項。所有選項值都可以是字串常值或訊息範本,以範本字元 '{''}' 表示。
    名稱 Required? 說明
    certificate 必填 與私密金鑰相符的憑證 (PEM 格式)。
    private_key 必填 包含 PEM 格式私密金鑰的流程變數。
    c14_inclusive_elements 選用 以逗號分隔的命名空間 URI 清單 (而非前置字元),用於將 InclusiveElements 元素新增至 CanonicalizationMethod 元素。
    confirmation 選用 下列其中一項:
    • SignatureConfirmation 元素中的簽章值清單,用於簽署。如果沒有具有指定值的 SignatureConfirmation 元素,系統會插入該元素。
    • \*all\* 字串,表示來源文件中現有的任何 SignatureConfirmation 元素都會簽署。
    • 空字串,表示要插入空白的 SignatureConfirmation 元素。
    除了 elements-to-sign 中指定的元素外,這些確認簽章也必須一併提供。
    digest_method 選用 摘要演算法。有效值為 sha1sha256。預設值為 sha256
    ds_prefix 選用 要用做命名空間前置字元的簡單字串。
    elements_to_sign 選用 要簽署的元素 XPath 運算式陣列 (例如 ["soapenv:Body"])。
    expiry 選用 要插入 TimestampExpires 元素中的值。 輸入 120s、10m 和 4d 等值,分別表示 120 秒、10 分鐘和 4 天。預設為永不過期。
    ignore_security_header_placement 選用 布林值,用於指定是否要檢查未簽署酬載中現有 Security 標頭的刊登位置。為與部分舊版系統相容而提供。不建議設為 true,因為這可能會讓您的 API 遭受簽章包裝攻擊。預設值為 false
    issuer_name_style 選用 發卡機構名稱格式。有效值為 CNDN
    key_identifier_type 選用 金鑰 ID 類型。有效值為 BinarySecurityTokenBST_DIRECT_REFERENCEISSUER_SERIALRSA_KEY_VALUETHUMBPRINTX509_CERT_DIRECT。預設值為 BinarySecurityToken
    private_key_password 選用 私密金鑰的密碼 (如果私密金鑰經過加密)。
    signing_method 選用 簽署方式。有效值為 rsa-sha1rsa-sha256。預設值為 rsa-sha1,但強烈建議設為 rsa-sha256
    soap_version 選用 SOAP 版本,有效版本為 1.1 和 1.2。預設值為 1.1。
    transform_inclusive_elements 選用 以逗號分隔的命名空間 URI 清單 (而非前置字元),用於將 InclusiveElements 元素新增至 Transform 元素。

範例

以下範例說明如何簽署 SOAP 文件。並假設私密金鑰和憑證已載入至流程變數。

var signed = crypto.wsSecRsaSign(request.content, {
    'private_key': '{private.key.pem}', // Flow variable name
    'certificate': '{public.cert.pem}', // Flow variable name
    'elements_to_sign: 
        'wsu:Timestamp, soap:Body, wsa:To, wsa:MessageID',
    'signing_method': 'rsa-sha256',
    'digest_method': 'sha256',
    expires_in': '180s'
});

使用 WS-Security 和 X.509 憑證驗證 SOAP 文件

使用 WS-Security 和 RSA/X.509 驗證 SOAP 文件的數位簽名。Gaambo 會執行驗證,確保傳遞的引數有效。

crypto.wsSecRsaValidate()

驗證 SOAP 文件的數位簽章。

語法

crypto.wsSecRsaValidate(payload, options)

參數

  • payload - (字串) 含有要驗證的數位簽章的 SOAP 文件。
  • options - (Object) 驗證的設定選項。下表列出可用的設定選項。所有選項值都可以是字串常值或訊息範本,以範本字元 '{'''}' 表示。
    名稱 Required? 說明
    accept_subject_cns 選用 以半形逗號分隔的簽署者主體通用名稱 (CN) 清單。 如果任何簽章來自的 CN 與指定的 CN 不符,驗證就會失敗。
    accept_thumbprints 選用 以半形逗號分隔的憑證 SHA-1 指紋清單,這些憑證是可接受的簽署者。 如果任何簽章來自指紋與指定指紋不符的憑證,驗證就會失敗。請只指定 accept-thumbprintsaccept-thumbprints-256 其中之一。如果未提供 certificate 選項,則必須提供至少一個選項。
    accept_thumbprints_256 選用 以半形逗號分隔的憑證 SHA-256 指紋清單,這些憑證是可接受的簽署者。 如果任何簽章來自指紋與指定指紋不符的憑證,驗證就會失敗。請只指定 accept-thumbprintsaccept-thumbprints-256 其中之一。如果未提供 certificate 選項,則必須提供至少一個選項。
    certificate 選用 提供公開金鑰以驗證簽章的憑證。只有在簽署文件中的 KeyInfo 未明確提供憑證時,才需要使用這項屬性。
    digest_method 選用 支援的摘要方法。 有效值為 sha1sha256。如果省略,系統不會檢查摘要方法。
    ignore_certificate_expiry 選用 布林值,用於指定是否要忽略所提供憑證的有效日期。適合用於測試。 預設值為 false
    ignore_expiry 選用 布林值,用於指定評估 SOAP 文件有效性時,是否要忽略 Timestamp/Expires 欄位。預設值為 false
    ignore_security_header_placement 選用 布林值,用於指定是否要檢查簽署酬載中安全性標頭的位置。為與部分舊版系統相容而提供。不建議將這項設定設為 true,因為這可能會讓 API 遭受簽章包裝攻擊。 預設值為 false
    issuer_name_dn_comparison 選用 用來判斷兩個發行者名稱是否指涉同一實體的方法。 只有在簽署文件包含包裝 X509IssuerSerialissuer-name-styleKeyInfo 時,才適用這個屬性 (預設值)。KeyInfoX509IssuerSerialissuer-name-styleDN值可以是 {stringnormalreverseunordered} 其中之一。預設為 string
    issuer_name_dn_comparison_exclue_numeric_oids 選用 用來判斷兩個發行者名稱是否指涉同一實體的方法。只有在簽署文件包含包裝 X509IssuerSerialKeyInfo,且 issuer-name-styleDN (預設值),以及 issuer-name-dn-comparison 設為 normalreverseunordered 時,才適用這項設定。
    issuer_name_style 選用 發卡機構名稱格式。只有在簽署文件包含包裝 X509IssuerSerialKeyInfo 時,才使用這個屬性。X509IssuerSerial有效值包括 CNDN
    max_lifetime 選用 簽署文件的生命週期上限。輸入 120s、10m 和 4d 等值,分別表示 120 秒、10 分鐘和 4 天。如要使用這個選項,Timestamp 必須包含 CreatedExpires 元素。預設為無生命週期上限。
    require_expiry 選用 布林值,指定時間戳記是否需要到期時間。建議將此值保留為 true。預設值為 true
    required_sign_elements 選用 以半形逗號或空格分隔的 prefix:Tag 表單清單,指出必須簽署的元素。預設值為 soap:Body, wsu:Timestamp。如要在驗證時只要求時間戳記簽章,而非主體簽章,請將此值設為 wsu:Timestamp。如要驗證時只要求主體簽章,而不要求時間戳記,請將這個值設為 soap:Body。前置字元和標記須區分大小寫,除非有特殊原因,否則建議您將這個值設為預設值。
    signing_method 選用 簽署方法,必須與簽署文件中的簽署方法相符。 有效值為 rsa-sha1rsa-sha256。如果省略,系統不會檢查簽署方法。

範例

以下範例說明如何驗證已簽署的 SOAP 型 API。如果簽章無效,流程變數 wssec_error 會填入特定錯誤。

Var isValid = crypto.wsSecRsaValidate(request.content, {
        MaxLifetime: '300s',
        RequiredSignedElements: [
            '//*[local-name()=\'Body\']'
        ],
        IgnoreCertificateExpiry: false,
        TrustStore: '{truststore.pem}' // Flow variable with trusted certs
    });

 if (!isValid) {
   throw "invalid"
 }

使用 getHash() 取得任何支援的雜湊物件

範例

var _hash1 = crypto.getHash('MD5');

var _hash2 = crypto.getHash('SHA-1');

var _hash3 = crypto.getHash('SHA-256');

var _hash4 = crypto.getHash('SHA-512');

加密貨幣範例

try {
    // get values to use with hash functions
    var salt = context.getVariable("salt") || 'SomeHardCodedSalt';
    var host = context.getVariable("request.header.Host");
    var unhashedToken = "";

    var _timeNow = Number(context.getVariable('system.timestamp'));
    var now = crypto.dateFormat('YYYY-MM-DD HH:mm:ss.SSS','PST', _timeNow);
    unhashed_token = "|" + now + "|" + host

    // generate a hash with the unhashedToken:
    var sha512 = crypto.getSHA512();
    sha512.update(salt);
    sha512.update(unhashedToken);

    // convert to base64
    var base64Token = sha512.digest64();

    // set headers
    context.setVariable("request.header.now", now);
    context.setVariable("request.header.token", base64Token);

} catch(e) {
    throw 'Error in Javascript';
}

背景資訊物件參考資料

系統會為 API Proxy 執行的每項要求/回應交易建立 context 物件。context 物件會公開方法,用來取得、設定及移除與每筆交易相關的變數。

變數會定義交易專屬的屬性。要求用戶端的時區、語言代碼、使用者代理程式,以及目標服務的網址,都是 context 中可用的變數範例。因此,context 可用於建構依賴這些屬性的邏輯,以執行自訂行為。

請參閱「流程變數參考資料」和「ExtractVariables 政策」。

背景資訊 物件摘要

下表簡要說明內容物件及其子項,並列出繫結至各個物件的屬性。

名稱 說明 屬性
context 訊息處理管道內容和要求/回應的包裝函式,以及由 ProxyEndpoint 和 TargetEndpoint 執行的流程。 流程、工作階段
context.proxyRequest 代表傳送至 ProxyEndpoint 的要求訊息 (從要求應用程式傳送至 API Proxy) 的物件 標頭、查詢參數、方法、主體、網址
context.targetRequest 這個物件代表從 TargetEndpoint 傳出的要求訊息 (從 API Proxy 到後端服務)。 標頭、查詢參數、方法、主體、網址
context.targetResponse 代表內送目標回應訊息的物件 (從後端服務到 API Proxy) 標頭、內容、狀態
context.proxyResponse 代表外送 Proxy 回應訊息的物件 (從 API Proxy 到要求應用程式) 標頭、內容、狀態
context.flow 目前流程的名稱。 請參閱 context.flow
context.session 名稱/值組合的地圖,可用於在相同環境中執行的兩個不同步驟之間傳遞物件。例如 context.session['key'] = 123 如要進一步瞭解何時應使用這個物件,請參閱「context.session['hello'] = {} 和 context.setVariable("hello", {}) 之間有何差異?」一文。

context object methods

context.getVariable()

擷取預先定義或自訂變數的值。

語法

context.getVariable("variable-name");

範例

如要取得當年度的值,請按照下列步驟操作:

var year = context.getVariable('system.time.year');

context.setVariable()

設定自訂變數的值,或任何可寫入預先定義變數

語法

context.setVariable("variable-name", value);

範例

設定變數的常見情境是 API Proxy 必須動態寫入目標網址。下列 JavaScript 會取得名為 USER.name 的變數值,將該值附加為網址 http://mocktarget.apigee.net?user= 的查詢參數,然後將預先定義的 target.url 設為該值。

context.setVariable("target.url", "http://mocktarget.apigee.net/user?user="+context.getVariable("USER.name"));

context.removeVariable()

從內容中移除變數。

語法

context.removeVariable('variable-name');

背景資訊物件屬性

context.flow

flow 屬性是識別目前 API Proxy 流程的字串。這項屬性用於指出 JavaScript 所附加的流程。支援的值如下:

  • PROXY_REQ_FLOW
  • PROXY_RESP_FLOW
  • TARGET_REQ_FLOW
  • TARGET_RESP_FLOW

每個流程名稱都包含 PreFlow、PostFlow,以及在 ProxyEndpoint 或 TargetEndpoint 中定義的任何條件流程。

如果要在多個流程中執行常見的 JavaScript,但其行為可能會因執行流程而異,這個選用屬性就很有用。如果 JavaScript 模組要在多個 API Proxy 中重複使用,請使用 Flow 屬性,因為程式碼必須先檢查目前的 Flow,才能執行邏輯。

示例

僅在 targetRequest Flow 上設定 HTTP 標頭:

if (context.flow=="TARGET_REQ_FLOW") {
     context.targetRequest.headers['TARGET-HEADER-X']='foo';
}

僅在 proxyResponse Flow 中設定內容:

if (context.flow=="PROXY_RESP_FLOW") {
     context.proxyResponse.content='bar';
}

context.session

名稱/值組合的對應,可用於在同一訊息環境中執行的兩項政策之間傳遞物件。

示例

在工作階段中設定值:

context.session['key']  = 123;

從工作階段取得值:

var value = context.session['key']; // 123

背景資訊物件子項

如下所示,完整的 API Proxy 流程包含四個不同的階段,每個階段都有相關聯的訊息物件,這些物件是內容物件的子項:

  • context.proxyRequest:從要求用戶端收到的傳入要求訊息。
  • context.targetRequest:傳送至後端服務的外送要求訊息。
  • context.proxyResponse:傳回給要求用戶端的外送回覆訊息。
  • context.targetResponse:從後端服務收到的入埠要求訊息。

圖表:要求和回應通過 Proxy 端點和目標端點。

以下各節說明這些物件的方法和屬性:

context.*Request 子項物件

在 API Proxy 中執行的每筆 HTTP 交易,都會建立兩個要求訊息物件:一個是傳入 (來自用戶端的要求),另一個是傳出 (API Proxy 產生並提交至後端目標的要求)。

context 物件有代表這些要求訊息的子項物件:context.proxyRequestcontext.targetRequest。這些物件可讓您在 JavaScript 程式碼執行時,存取要求流程中範圍內的屬性。

context.*Request 子項物件屬性

屬性名稱 說明
url

url 屬性是讀取/寫入便利屬性,可合併 targetRequest 的配置、主機、通訊埠、路徑和查詢參數。

要求的完整網址是由下列屬性組成:

  • 通訊協定:網址的通訊協定 (例如 HTTP、HTTPS)
  • 通訊埠:通訊埠 (例如:80、443)
  • 主機:網址的主機 (例如 www.example.com)
  • 路徑:URI 的路徑 (例如 /v1/mocktarget)

取得 url 時,系統會傳回下列格式的網址:

protocol://host:port/path?queryParams

範例:

context.targetRequest.url = 'http://www.example.com/path?q1=1'
context.targetRequest.protocol ='https';
headers

HTTP 要求標頭,以 String => List 的對應形式表示

範例:

這個 HTTP 要求:

POST /v1/blogs HTTP/1.1
Host: api.example.com
Content-Type: application/json
Authorization: Bearer ylSkZIjbdWybfs4fUQe9BqP0LH5Z
下列 JavaScript:
context.proxyRequest.headers['Content-Type'];
context.proxyRequest.headers['Authorization'];

會傳回下列值

application/json
Bearer ylSkZIjbdWybfs4fUQe9BqP0LH5Z
queryParams

要求訊息查詢參數,以 String => List 的對應形式表示。

範例:

"?city=PaloAlto&city=NewYork"

可存取為:

context.proxyRequest.queryParams['city'];  // == 'PaloAlto'
context.proxyRequest.queryParams['city'][0]     // == 'PaloAlto'
context.proxyRequest.queryParams['city'][1];    // == 'NewYork'
context.proxyRequest.queryParams['city'].length(); // == 2
method

HTTP 動詞 (GET、POST、PUT、DELETE。PATCH 等)

範例:

這項要求:

POST /v1/blogs HTTP/1.1
Host: api.example.com
Content-Type: application/json
Authorization: Bearer ylSkZIjbdWybfs4fUQe9BqP0LH5Z

以下 JavaScript:

context.proxyRequest.method;

會傳回下列值

POST
body

HTTP 要求的訊息內文 (酬載)。

要求主體包含下列成員:

  • context.targetRequest.body.asXML;
  • context.targetRequest.body.asJSON;
  • context.targetRequest.body.asForm;

範例:

如果是 XML 內文:

<customer number='1'>
<name>Fred<name/>
<customer/>

如要存取 XML 物件的元素,請按照下列步驟操作:

var name = context.targetRequest.body.asXML.name;

如要存取 XML 屬性,請使用 @ 標記。

var number = context.targetRequest.body.asXML.@number;

JSON 要求主體:

{
"a":  1 ,
"b" : "2"
}
var a = context.proxyRequest.body.asJSON.a;    // == 1
var b = context.proxyRequest.body.asJSON.b;    // == 2

如要讀取表單參數:

"vehicle=Car&vehicle=Truck"
v0 = context.proxyRequest.body.asForm['vehicle'][0];
v1 = context.proxyRequest.body.asForm['vehicle'][1];

context.*Response 子項物件

對於在 API Proxy 中執行的每筆 HTTP 交易,系統會建立兩個回應訊息物件:一個是傳入 (來自後端服務的回應),另一個是傳出 (傳回給用戶端的回應)。

內容物件有子項物件,代表這些回應訊息:context.proxyResponsecontext.targetResponse。這些物件可讓您在 JavaScript 程式碼執行時,存取回應流程中範圍內的屬性。

context.*回應物件屬性

屬性名稱 說明
headers

回應訊息的 HTTP 標頭,以 String => List 的對應形式表示。

範例:

var cookie = context.targetResponse.headers['Set-Cookie'];
status

狀態碼,並以屬性形式提供狀態訊息。狀態碼和狀態訊息都可做為屬性。

範例:

var status = context.targetResponse.status.code;   // 200
var msg = context.targetResponse.status.message;   // "OK"
content

回應訊息的 HTTP 主體 (酬載內容)。

回應內容包含下列成員:

context.targetResponse.content.asXML;
context.targetResponse.content.asJSON;

使用 .asXML 標記法

您可以使用 .asXML 標記,輕鬆逐步瀏覽 XML 文件。 本節說明如何使用這項標記,以及這項標記與 request.contentcontext.proxyRequest.content 的差異。

例如:

request.content.asXML

context.proxyRequest.content.asXML

*.content*.content.asXML 形式都可用於字串環境,JavaScript 會強制將其轉換為字串。如果是前者 (*.content),字串會包含所有宣告和 XML 註解。在後者 (*.content.asXML) 的情況下,結果的字串值會清除宣告和註解。

範例

msg.content:

<?xml version="1.0" encoding="UTF-8"?>
<yahoo:error xmlns:yahoo="http://yahooapis.com/v1/base.rng" xml:lang="en-US">
   <yahoo:description>Please provide valid credentials. OAuth oauth_problem="unable_to_determine_oauth_type", realm="yahooapis.com"
   </yahoo:description>
</yahoo:error>
<!-- mg023.mail.gq1.yahoo.com uncompressed/chunked Sat Dec 14 01:23:35 UTC 2013 -->

msg.content.asXML:

<?xml version="1.0" encoding="UTF-8"?>
<yahoo:error xmlns:yahoo="http://yahooapis.com/v1/base.rng" xml:lang="en-US">
   <yahoo:description>Please provide valid credentials. OAuth oauth_problem="unable_to_determine_oauth_type", realm="yahooapis.com"
   </yahoo:description>
</yahoo:error>

此外,您也可以指定元素和屬性的名稱,使用 .asXML 表單遍歷 XML 階層。無法使用其他語法遍歷階層。

使用 JavaScript 執行偵錯 print() 陳述式

如果您使用 JavaScript 政策執行自訂 JavaScript 程式碼,請注意,您可以使用 print() 函式將偵錯資訊輸出至偵錯工具。這項函式可直接透過 JavaScript 物件模型使用。例如:

if (context.flow=="PROXY_REQ_FLOW") {
     print("In proxy request flow");
     var username = context.getVariable("request.queryparam.user");
     print("Got query param: " + username);
     context.setVariable("USER.name", username);
     print("Set query param: " + context.getVariable("USER.name"));
}


if (context.flow=="TARGET_REQ_FLOW") {
     print("In target request flow");
     var username = context.getVariable("USER.name");
     var url = "http://mocktarget.apigee.net/user?"
     context.setVariable("target.url", url + "user=" + username);
     print("Callout to URL: ", context.getVariable("target.url"));
}

如要查看輸出內容,請選取「Debug」視窗底部的「Output from all transactions」。您也可以在名為 stepExecution-stdout 的「偵錯」屬性中找到輸出內容。

使用 httpClient 進行 JavaScript 呼叫

在 API Proxy 流程中執行的自訂 JavaScript 程式碼內,使用 httpClient 對任何網址發出多個並行非同步 HTTP 要求。httpClient 物件是由 Apigee JavaScript 物件模型公開。

關於 httpClient

httpClient 物件會透過 JavaScript 物件模型,公開給在 Apigee 上執行的自訂 JavaScript 程式碼。如要將自訂 JavaScript 附加至 API Proxy,請使用 JavaScript 政策。政策執行時,系統會執行自訂 JavaScript 程式碼。

httpClient 物件可用於開發複合服務或混搭服務。舉例來說,您可以將多個後端呼叫合併為單一 API 方法。

以下是基本的使用模式。建立 Request 物件的例項,為該物件指派網址 (例如要呼叫的後端服務),然後使用該要求物件呼叫 httpClient.send

var myRequest = new Request();
myRequest.url = "http://www.example.com";
var exchangeObj = httpClient.send(myRequest);

httpClient 參考資料

HTTP 用戶端會公開兩種方法:get()send()

httpClient.get()

簡單 HTTP GET 要求的便利方法,不支援 HTTP 標頭。

用量

var exchangeObj = httpClient.get(url);

退貨

這個方法會傳回 exchange 物件。這個物件沒有屬性,但會顯示下列方法:

  • isError():(布林值) 如果 httpClient 無法連線至伺服器,則傳回 true。HTTP 狀態碼 4xx5xx 會導致 isError() false,因為連線已完成,且傳回了有效的狀態碼。如果 isError() 傳回 true,則呼叫 getResponse() 會傳回 JavaScript undefined
  • isSuccess():(布林值) 如果傳送作業完成且成功,則傳回 true
  • isComplete():(布林值) 如果要求完成,則傳回 true
  • waitForComplete():暫停執行緒,直到要求完成 (成功或發生錯誤)。
  • getResponse():(物件) 如果 httpClient.send() 完成且成功,則傳回回應物件。傳回的物件具有與 context.proxyResponse 物件相同的方法和屬性。請參閱內容物件摘要
  • getError():(字串) 如果呼叫 httpClient.send() 導致錯誤,則會以字串形式傳回錯誤訊息。

示例

傳送已完整設定的 Request 物件,其中包含 HTTP 要求的屬性。使用非封鎖回呼處理回應。

// Add the required the headers for making a specific API request
var headers = {'X-SOME-HEADER' : 'some value' };
// Make a GET API request along with headers
var myRequest = new Request("http://www.example.com","GET",headers);

// Define the callback function and process the response from the GET API request
function onComplete(response,error) {
 // Check if the HTTP request was successful
    if (response) {
      context.setVariable('example.status', response.status);
     } else {
      context.setVariable('example.error', 'Woops: ' + error);
     }
}

// Specify the callback Function as an argument
httpClient.get(myRequest, onComplete);

使用 JavaScript 政策

使用 JavaScript 政策將自訂 JavaScript 程式碼附加至 Proxy 流程。 請參閱「 JavaScript 政策」。

相關主題