JavaScript 政策

您正在查看 Apigee Edge 說明文件。
查看 Apigee X 說明文件
資訊

優勢

這項政策可讓您新增自訂 JavaScript 程式碼,程式碼會在 API Proxy 流程環境內執行。在自訂 JavaScript 程式碼中,您可以使用 Apigee Edge JavaScript 物件模型的物件、方法和屬性。物件模型可讓您取得、設定及移除 Proxy 流程環境中的變數。您也可以使用物件模型隨附的基本加密編譯函式。

About

JavaScript 政策的用途很多,舉例來說,您可以取得並設定流程變數、執行自訂邏輯並執行錯誤處理、從要求或回應擷取資料、動態編輯後端目標網址等。這項政策可讓您實作其他標準 Edge 政策未涵蓋的自訂行為。事實上,您可以使用 JavaScript 政策來實現由其他政策實作的許多相同行為,例如 AssignMessage 和 ExtractVariable。

我們不建議設定 JavaScript 政策的其中一個用途。訊息記錄政策更適合用來記錄至第三方記錄平台 (例如 Splunk、Sumo 和 Loggly),且您藉由在 PostClientFlow 中執行訊息記錄政策 (系統會在回應傳回用戶端後執行該政策) 改善 API Proxy 效能。

JavaScript 政策可讓你指定要執行的 JavaScript 來源檔案,或是透過 <Source> 元素直接在政策設定中加入 JavaScript 程式碼。 不論是哪一種方式,執行政策的步驟時都會執行 JavaScript 程式碼。如為來源檔案選項,原始碼一律儲存在 Proxy 組合中的標準位置:apiproxy/resources/jsc。或者,您也可以將原始碼儲存在環境或機構層級的資源檔案中。如需操作說明,請參閱「資源檔案」一節。您也可以透過 Apigee UI Proxy 編輯器上傳 JavaScript。

JavaScript 來源檔案一律有 .js 副檔名。

如要瞭解目前支援的 JavaScript 版本,請參閱支援的軟體和支援的版本

影片

請觀看短片,瞭解如何使用 JavaScript 政策建立自訂政策擴充功能。

範例

重新編寫目標網址

常見的用途如下:從要求主體擷取資料、將資料儲存在流程變數中,以及將該流程變數用於 Proxy 流程的其他位置。假設您有一個應用程式,使用者在 HTML 表單中輸入自己的名稱並提交,您想要 API Proxy 擷取表單資料,並動態將其新增至呼叫後端服務的網址。如何在 JavsScript 政策中執行這項操作?

注意:如要試用這個範例,我們假設您已透過 Proxy 編輯器建立新的 Proxy。建立後端網址時,只要提供後端服務網址即可:http://www.example.com。在這個範例中,我們會以動態方式重寫後端網址。如果您不知道如何建立新的 Proxy,請參閱入門教學課程。.

  1. 在 Edge UI 中,開啟您在 Proxy 編輯器中建立的 Proxy。
  2. 選取「開發」分頁標籤。
  3. 從「新增」選單中選取「新增指令碼」
  4. 在對話方塊中選取 JavaScript 並為指令碼命名,例如 js-example
  5. 將下列程式碼貼入程式碼編輯器,然後儲存 Proxy。請務必留意 context 物件。這個物件可在 Proxy 流程中的任何位置供 JavaScript 程式碼使用。可用於取得資料流專屬的常數、呼叫實用的 get/set 方法,以及執行更多作業。這個物件部分屬於 Edge 的 JavaScript 物件模型。另請注意,target.url 流程變數是內建、讀取/寫入變數,可在「目標要求」流程中存取。使用 API 網址設定該變數時,Edge 會對該網址進行後端呼叫。我們基本上會改寫原始目標網址,也就是您建立 Proxy 時指定的網址 (例如 http://www.example.com).

    if (context.flow=="PROXY_REQ_FLOW") {
         var username = context.getVariable("request.formparam.user");
         context.setVariable("info.username", username);
    }
    
    
    if (context.flow=="TARGET_REQ_FLOW") {
         context.setVariable("request.verb", "GET");
         var name = context.getVariable("info.username");
         var url = "http://mocktarget.apigee.net/"
         context.setVariable("target.url", url + "?user=" + name);
    }
    
  6. 從「新增政策」選單中選取「JavaScript」JavaScript
  7. 為政策命名,例如 target-rewrite。接受預設值,然後儲存政策。
  8. 如果您在「Navigator」中選取 Proxy 端點預先流,就會看到該政策已新增至該流程。
  9. 在「Navigator」中,選取「Target Endpoint PreFlow」圖示。
  10. 在導覽工具中,將 JavaScript 政策拖曳到流程編輯器中的目標端點「要求」端。
  11. Save.
  12. 按照下方方式呼叫 API,請視情況替換正確的機構名稱和 Proxy 名稱:
curl -i -H 'Content-Type: application/x-www-form-urlencoded' -X POST -d 'user=Will' http://myorg-test.apigee.net/js-example

最後再探討這個範例中使用的 JavaScript 政策 XML 定義。請特別注意,<ResourceURL> 元素是用來指定要執行的 JavaScript 來源檔案。同樣的模式適用於所有 JavaScript 來源檔案:jsc://filename.js。如果您的 JavaScript 程式碼需要包含,可以使用一或多個 <IncludeURL> 元素執行此作業,詳情請參閱這份參考資料後續章節。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Javascript async="false" continueOnError="false" enabled="true" timeLimit="200" name="target-rewrite">
    <DisplayName>target-rewrite</DisplayName>
    <Properties/>
    <ResourceURL>jsc://js-example.js</ResourceURL>
</Javascript>

從 JavaScript 擷取屬性值

您可以在設定中新增 <Property> 元素,然後在執行階段透過 JavaScript 擷取元素的值。

使用元素的 name 屬性,指定從 JavaScript 程式碼存取屬性的名稱。<Property> 元素的值 (開頭和結尾標記之間的值) 是 JavaScript 會接收的常值。

在 JavaScript 中,您可以透過存取 Properties 物件的屬性來擷取政策屬性值,如下所示:

  • 設定屬性。這裡的屬性值是變數名稱 response.status.code
    <Javascript async="false" continueOnError="false" enabled="true" timeLimit="200" name="JavascriptURLRewrite">
        <DisplayName>JavascriptURLRewrite</DisplayName>
        <Properties>
            <Property name="source">response.status.code</Property>
        </Properties>
        <ResourceURL>jsc://JavascriptURLRewrite.js</ResourceURL>
    </Javascript>
    
  • 使用 JavaScript 擷取屬性。這裡,擷取到的值 (變數名稱),getVariable 函式隨後會使用這個值來擷取變數的值。
    var responseCode = properties.source; // Returns "response.status.code"
    var value = context.getVariable(responseCode); // Get the value of response.status.code
    context.setVariable("response.header.x-target-response-code", value);
    

處理錯誤

如要查看可在 JavaScript 呼叫中使用的錯誤處理技巧範例和討論,請參閱 這篇 Apigee 社群的貼文。Apigee 社群提供的建議僅供參考,不一定是 Apigee 建議的最佳做法。


元素參照

元素參考資料說明 JavaScript 政策的元素和屬性。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Javascript async="false" 
        continueOnError="false" enabled="true" timeLimit="200" 
        name="JavaScript-1">
    <DisplayName>JavaScript 1</DisplayName>
    <Properties>
        <Property name="propName">propertyValue</Property>
    </Properties>
    <SSLInfo>
        <Enabled>trueFalse</Enabled>
        <ClientAuthEnabled>trueFalse</ClientAuthEnabled>
        <KeyStore>ref://keystoreRef</KeyStore>
        <KeyAlias>keyAlias</KeyAlias>
        <TrustStore>ref://truststoreRef</TrustStore>
    </SSLInfo>
    <IncludeURL>jsc://a-javascript-library-file</IncludeURL>
    <ResourceURL>jsc://my-javascript-source-file</ResourceURL>
    <Source>insert_js_code_here</Source>

</Javascript>

<JavaScript> 屬性

<Javascript name="Javascript-1" enabled="true" continueOnError="false" async="false" timeLimit="200">

下列屬性專屬於這項政策,

屬性 說明 預設 存在必要性
timeLimit

指定指令碼的執行時間上限 (以毫秒為單位)。舉例來說,如果超過 200 毫秒的長度上限,這項政策就會擲回以下錯誤:Javascript.policy_name failed with error: Javascript runtime exceeded limit of 200ms

注意:免費試用帳戶的執行時間上限為 200 毫秒。

不適用 需要

下表說明所有政策父項元素的通用屬性:

屬性 說明 預設 存在必要性
name

政策的內部名稱。name 屬性的值可以包含英文字母、數字、空格、連字號、底線和半形句號。這個值不得超過 255 個半形字元。

您也可以選擇使用 <DisplayName> 元素,在管理 UI Proxy 編輯器中使用不同的自然語言名稱為政策加上標籤。

不適用 需要
continueOnError

如果設為 false,即可在政策失敗時傳回錯誤。大部分政策都是預期中的行為。

設為 true,即可在政策失敗後繼續執行資料流。

false 選用
enabled

如要強制執行政策,請設為 true

設為 false 即可停用這項政策。即使政策仍附加在流程中,系統也不會強制執行政策。

true 選用
async

此屬性已淘汰。

false 已淘汰

<DisplayName> 元素

除了 name 屬性外,您還可以使用不同的自然語言名稱,在管理 UI Proxy 編輯器中為政策加上標籤。

<DisplayName>Policy Display Name</DisplayName>
預設

不適用

如果省略這個元素,系統會使用政策的 name 屬性值。

存在必要性 選用
類型 字串

<IncludeURL> 元素

指定要以 <ResourceURL><Source> 元素指定的主要 JavaScript 檔案依附元件載入的 JavaScript 程式庫檔案。系統會按照政策中列出的順序評估指令碼。您的程式碼可以使用 JavaScript 物件模型的物件、方法和屬性。

加入多個 JavaScript 依附元件資源,以及額外的 <IncludeURL> 元素。

<IncludeURL>jsc://my-javascript-dependency.js</IncludeURL>
預設:
所在地: 選用
類型: 字串

範例

請參閱「範例」部分中的基本範例。

<Property> 元素

指定您可以在執行階段從 JavaScript 程式碼存取的屬性。

<Properties>
    <Property name="propName">propertyValue</Property>
</Properties>
預設:
所在地: 選用
類型: 字串

屬性

屬性 說明 預設 存在必要性
名稱

指定屬性名稱。

不適用 這是必填欄位。

範例

請參閱範例一節中的範例。

<ResourceURL> 元素

指定要在 API 流程中執行的主要 JavaScript 檔案。您可以將這個檔案儲存在 API Proxy 範圍 (API Proxy 套件的 /apiproxy/resources/jsc 之下或 API Proxy 編輯器「Navigator」窗格的「Scripts」區段內),或是在機構或環境範圍中供多個 API Proxy 重複使用,如資源檔案中所述。您的程式碼可以使用 JavaScript 物件模型的物件、方法和屬性。

<ResourceURL>jsc://my-javascript.js</ResourceURL>
預設:
所在地: 必須提供 <ResourceURL><Source> 兩者之一。如果 <ResourceURL><Source> 都存在,系統會忽略 <ResourceURL>
類型: 字串

範例

請參閱「範例」部分中的基本範例。

<Source> 元素

允許您將 JavaScript 直接插入政策的 XML 設定。當政策在 API 流程中執行時,系統就會執行插入的 JavaScript 程式碼。

預設:
所在地: 必須提供 <ResourceURL><Source> 兩者之一。如果 <ResourceURL><Source> 都存在,系統會忽略 <ResourceURL>
類型: 字串

範例

<Javascript name='JS-ParseJsonHeaderFullString' timeLimit='200' >
  <Properties>
    <Property name='inboundHeaderName'>specialheader</Property>
    <Property name='outboundVariableName'>json_stringified</Property>
  </Properties>
  <Source>
var varname = 'request.header.' + properties.inboundHeaderName + '.values.string';
var h = context.getVariable(varname);
if (h) {
  h = JSON.parse(h);
  h.augmented = (new Date()).valueOf();
  var v = JSON.stringify(h, null, 2) + '\n';
  // further indent
  var r = new RegExp('^(\S*)','mg');
  v= v.replace(r,'    $1');
  context.setVariable(properties.outboundVariableName, v);
}
  </Source>
</Javascript>

<SSLInfo> 元素

指定用來為 JavaScript 政策建立的所有 HTTP 用戶端執行個體設定 TLS 的屬性。

    <SSLInfo>
        <Enabled>trueFalse</Enabled>
        <ClientAuthEnabled>trueFalse</ClientAuthEnabled>
        <KeyStore>ref://keystoreRef</KeyStore>
        <KeyAlias>keyAlias</KeyAlias>
        <TrustStore>ref://truststoreRef</TrustStore>
    </SSLInfo>
預設:
所在地: 選用
類型: 字串

為 HTTP 用戶端設定 TLS 的程序與為 TargetEndpoint/TargetServer 設定 TLS 的程序相同。 詳情請參閱「設定從 Edge 到後端的 TLS」。

使用須知

JavaScript 政策不含任何實際程式碼。相反地,JavaScript 政策會參照 JavaScript「資源」,並在執行 JavaScript 的 API 流程中定義步驟。您可以透過管理 UI Proxy 編輯器上傳指令碼,也可以在在本機開發的 API Proxy 中,將指令碼加入 /resources/jsc 目錄。

對 JavaScript 政策程式碼進行偵錯

使用 print() 函式,將偵錯資訊輸出至追蹤工具中的交易輸出面板。如需瞭解詳情和範例,請參閱使用 JavaScript print() 陳述式進行偵錯。

如何在 Trace 中查看輸出陳述式:

  1. 開啟追蹤工具,然後針對包含您 JavaScript 政策的 Proxy 啟動追蹤工作階段。
  2. 呼叫 Proxy。
  3. 在追蹤記錄工具中,按一下「Output from all Transactions」(所有交易的輸出內容) 開啟輸出面板。

  4. 你的列印對帳單會顯示在這個面板中。

您可以使用 print() 函式將偵錯資訊輸出至追蹤記錄工具。這個函式可直接透過 JavaScript 物件模型使用。詳情請參閱「使用 print() 陳述式對 JavaScript 進行偵錯」。

流程變數

根據預設,這項政策不會填入任何變數;不過,您可以藉由呼叫結構定義物件的方法,在 JavaScript 程式碼中設定 (及 get) 流程變數。典型的模式如下:

context.setVariable("response.header.X-Apigee-Target", context.getVariable("target.name"))

情境物件是 Apigee Edge JavaScript 物件模型的一部分。

錯誤參考資料

本節說明當這項政策觸發錯誤時,傳回的錯誤代碼和錯誤訊息,以及 Edge 設定的錯誤變數。如果您開發的錯誤規則來處理錯誤,請務必瞭解這些資訊。詳情請參閱「政策錯誤須知」和「處理錯誤」。

執行階段錯誤

執行政策時,可能會發生這些錯誤。

錯誤代碼 HTTP 狀態 原因 修正
steps.javascript.ScriptExecutionFailed 500 JavaScript 政策可能會擲回多種不同類型的 ScriptExecutionFailed 錯誤。常見的錯誤類型包括 RangeErrorReferenceErrorSyntaxErrorTypeErrorURIError
steps.javascript.ScriptExecutionFailedLineNumber 500 JavaScript 程式碼發生錯誤。詳情請參閱錯誤字串。 不適用
steps.javascript.ScriptSecurityError 500 執行 JavaScript 時發生安全性錯誤。詳情請參閱錯誤字串。 不適用

部署錯誤

若您部署包含這項政策的 Proxy,就可能會發生這些錯誤。

錯誤名稱 原因 修正
InvalidResourceUrlFormat 如果 <ResourceURL> 或 JavaScript 政策的 <IncludeURL> 元素中指定的資源網址格式無效,API Proxy 部署就會失敗。
InvalidResourceUrlReference 如果 <ResourceURL><IncludeURL> 元素參照的 JavaScript 檔案不存在,API Proxy 的部署作業就會失敗。參照的來源檔案必須位於 API Proxy、環境或機構層級。
WrongResourceType 如果 JavaScript 政策的 <ResourceURL><IncludeURL> 元素參照 jsc (JavaScript 檔案) 以外的任何資源類型,系統就會在部署期間發生這個錯誤。
NoResourceURLOrSource 如未宣告 <ResourceURL> 元素,或未在此元素中定義資源網址,JavaScript 政策的部署作業可能會失敗。<ResourceURL> 元素是必要元素。或者,系統會宣告 <IncludeURL> 元素,但這個元素中並未定義資源網址。<IncludeURL> 元素為選用元素,但如果已宣告,則必須在 <IncludeURL> 元素中指定資源網址。

錯誤變數

當這項政策在執行階段觸發錯誤時,系統會設定這些變數。詳情請參閱「政策錯誤須知」。

Variables 地點 範例
fault.name="fault_name" fault_name 是錯誤的名稱,如上方的「執行階段錯誤」表格所示。錯誤名稱是錯誤碼的最後一個部分。 fault.name Matches "ScriptExecutionFailed"
javascript.policy_name.failed policy_name 是擲回錯誤的政策使用者指定的名稱。 javascript.JavaScript-1.failed = true

錯誤回應範例

{
  "fault": {
    "faultstring": "Execution of SetResponse failed with error: Javascript runtime error: "ReferenceError: "status" is not defined. (setresponse.js:6)\"",
    "detail": {
      "errorcode": "steps.javascript.ScriptExecutionFailed"
    }
  }
}

故障規則示例

<FaultRule name="JavaScript Policy Faults">
    <Step>
        <Name>AM-CustomErrorResponse</Name>
        <Condition>(fault.name Matches "ScriptExecutionFailed") </Condition>
    </Step>
    <Condition>(javascript.JavaScript-1.failed = true) </Condition>
</FaultRule>

結構定義

每個政策類型都是由 XML 結構定義 (.xsd) 定義。如需參考,GitHub 提供政策結構定義

相關主題

Apigee 社群文章

您可以前往 Apigee 社群找到下列相關文章: