JavaScript 政策

本頁適用於 ApigeeApigee Hybrid

查看 Apigee Edge 說明文件。

政策圖示

結果

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

這項政策是可擴充的政策,視您的 Apigee 授權而定,使用這項政策可能會產生費用或使用量影響。如要瞭解政策類型和使用相關性,請參閱「政策類型」。

關於

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

我們不建議在 JavaScript 政策中使用記錄功能。MessageLogging 政策更適合記錄至第三方記錄平台 (例如 Splunk、Sumo 和 Loggly),您可以在 PostClientFlow 中執行 MessageLogging 政策,以便在回傳回應後執行此政策,進而提升 API 代理程效能。

您可以使用 JavaScript 政策指定要執行的 JavaScript 來源檔案,也可以使用 <Source> 元素,直接在政策設定中加入 JavaScript 程式碼。無論是哪種情況,系統都會在政策附加的步驟執行時執行 JavaScript 程式碼。對於來源檔案選項,原始碼一律會儲存在 Proxy 套件中的標準位置:apiproxy/resources/jsc。您也可以在環境或機構層級的資源檔案中儲存原始碼。如需操作說明,請參閱「資源檔案」一文。您也可以透過 Apigee UI 代理編輯器上傳 JavaScript。

JavaScript 來源檔案的副檔名一律必須是 .js

Apigee 支援在 Rhino JavaScript 引擎 1.7.13 上執行的 JavaScript。

影片

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

範例

重寫目標網址

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

  1. 在 Apigee UI 中,開啟在 Proxy 編輯器中建立的 Proxy。
  2. 選取「開發」分頁標籤。
  3. 在「新增」選單中,選取「新指令碼」
  4. 在對話方塊中選取 JavaScript,並為指令碼命名,例如 js-example
  5. 將下列程式碼貼到程式碼編輯器中,然後儲存 Proxy。請注意 context 物件。這個物件可供 Proxy 流程中的任何位置的 JavaScript 程式碼使用。這項元素用於取得特定流量的常數、呼叫實用的 get/set 方法,以及執行更多作業。這個物件部分屬於 Apigee 的 JavaScript 物件模型。請注意,target.url 流程變數是內建的讀/寫變數,可在目標要求流程中存取。當我們使用 API 網址設定該變數時,Apigee 會對該網址進行後端呼叫。我們基本上已重寫原始目標網址,也就是您建立 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. 如果在導覽器中選取 Proxy Endpoint Preflow,您會看到政策已新增至該流程。
  9. 在導覽器中選取「Target Endpoint PreFlow」圖示。
  10. 在導覽器中,將 JavaScript 政策拖曳至流程編輯器中目標端點的「Request」端。
  11. 請呼叫 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 呼叫中可用的錯誤處理技術範例和相關討論,請參閱「 從 JavaScript 政策傳回錯誤的正確方式」。Apigee 社群提供的建議僅供參考,不一定代表 Google 建議的最佳做法。


元素參照

元素參考資料會說明 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

不適用 必填

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

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

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

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

不適用 必填
continueOnError

將其設為 false,即可在政策失敗時傳回錯誤。這是大多數政策的預期行為。

將其設為 true,即使政策失敗,流程執行作業仍會繼續進行。另請參閱:

false 選用
enabled

設為 true 即可強制執行政策。

設為 false 即可關閉政策。即使政策仍附加至流程中,也不會強制執行。

選用
async

此屬性已淘汰。

false 已淘汰

<DisplayName> 元素

除了 name 屬性之外,您也可以在管理 UI 代理程式編輯器中使用不同的自然語言名稱標示政策。

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

不適用

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

存在必要性 選用
類型 字串

<IncludeURL> 元素

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

使用其他 <IncludeURL> 元素加入多個 JavaScript 相依性資源。

<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 窗格中的「Script」部分),或是儲存在組織或環境範圍,以便在多個 API Proxy 中重複使用,如「管理資源」一文所述。程式碼可使用 JavaScript 物件模型的物件、方法和屬性。

<ResourceURL>jsc://my-javascript.js</ResourceURL>
預設值:
外觀狀態: 您必須使用 <ResourceURL><Source> 其中之一。如果同時提供 <ResourceURL><Source>,系統會忽略 <ResourceURL>
類型: 字串

範例

請參閱「範例」一節中的基本範例。

<Source> 元素

可讓您直接將 JavaScript 插入政策的 XML 設定中。插入的 JavaScript 程式碼會在政策在 API 流程中執行時執行。

預設值:
外觀狀態: 您必須使用 <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 的程序相同。詳情請參閱「傳輸層安全標準 (TLS) 設定選項」一文。

使用須知

對 JavaScript 政策程式碼偵錯

使用 print() 函式,將偵錯資訊輸出至 Debug 工具中的交易輸出面板。如需詳細資訊和範例,請參閱「使用 JavaScript print() 陳述式偵錯」。

如要在「偵錯」中查看列印陳述式:

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

  4. 這個面板會顯示您的列印陳述式。

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

流程變數

根據預設,這項政策不會填入任何變數;不過,您可以透過在內容物件上呼叫方法,在 JavaScript 程式碼中設定 (和取得) 流程變數。典型模式如下所示:

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

內容物件是 Apigee JavaScript 物件模型的一部分。

錯誤參考資料

本節說明這項政策觸發錯誤時,Apigee 傳回的錯誤代碼和錯誤訊息,以及 Apigee 設定的錯誤變數。如果您要開發錯誤處理規則,就必須瞭解這項資訊。如需更多資訊,請參閱「關於政策錯誤的相關資訊」和「處理錯誤」。

執行階段錯誤

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

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

部署錯誤

部署含有這項政策的 Proxy 時,可能會發生這些錯誤。

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

錯誤變數

當這項政策在執行階段觸發錯誤時,系統就會設定這些變數。詳情請參閱「關於政策錯誤的相關資訊」。

變數 地點 範例
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 社群中找到下列相關文章: