注意:此产品的某些方面处于 Beta 版阶段。Hybrid 安装选项是 GA。要加入 Beta 版计划,请与您的 Apigee 代表联系。

JavaScript 政策

内容

此政策允许您添加在 API 代理流上下文中执行的自定义 JavaScript 代码。在自定义 JavaScript 代码中,您可以使用 Apigee JavaScript 对象模型的对象、方法和属性。对象模型让您可在代理流上下文中获取、设置和移除变量。您还可以使用随对象模型提供的基本加密函数。

简介

JavaScript 政策有许多用例。例如,您可以获取和设置流变量,执行自定义逻辑并执行故障处理,从请求或响应中提取数据,动态编辑后端目标网址,等等。该政策让您可实施任何其他标准 Apigee 政策未涵盖的自定义行为。实际上,您可以使用 JavaScript 政策来实现其他政策实施的许多行为,如 AssignMessage 和 ExtractVariable。

对于 JavaScript 政策,我们不建议的用例是日志记录。消息日志记录政策更适合记录到 Splunk,Sumo 和 Loggly 等第三方日志记录平台,并且您可通过在 PostClientFlow 中执行消息日志记录政策来提高 API 代理性能。PostClientFlow 在将响应发送回客户端后执行。

实际上,JavaScript 政策会指定要在执行将政策附加到的步骤时执行的 JavaScript 源文件的名称。源文件始终存储在代理软件包中的标准位置:apiproxy/resources/jsc。或者,您也可以将源代码存储在环境或组织级层的资源文件中。如需了解相关说明,请参阅资源文件。您还可以通过 Apigee 界面代理编辑器上传 JavaScript。

JavaScript 源文件必须始终具有 .js 扩展名。

如需了解当前支持的 JavaScript 版本,请参阅支持的软件和支持的版本

视频

观看短视频,了解如何使用 JavaScript 政策创建自定义政策扩展程序。

示例

重写目标网址

下面是一个常见的用例:从请求正文中提取数据,将其存储在流变量中,并在代理流的其他位置使用该流变量。假设您有一个应用,用户可以在 HTML 表单中输入其名称并提交该名称。您希望 API 代理提取表单数据,并将其动态添加到用于调用后端服务的网址。如何在 JavsScript 政策中执行此操作?

注意:如果您想试用此示例,我们假设您在代理编辑器中创建了一个新代理。创建代理时,您只需为其提供后端服务网址:http://www.example.com。在本示例中,我们将动态重写后端网址。如果您不知道如何创建新代理,请参阅使用入门教程。.

  1. 在 Apigee 界面中,打开您在代理编辑器中创建的代理。
  2. 选择开发标签页。
  3. 从“新建”菜单中,选择新建脚本
  4. 在对话框中,选择 JavaScript 并为脚本命名,例如 js-example
  5. 将以下代码粘贴到代码编辑器中,并保存代理。需要注意的是 context 对象。在代理流中的任何位置,您都可以在 JavaScript 代码中使用此对象。它用于获取流特定常量、调用有用的 get/set 方法以及执行更多操作。此对象部分属于 Apigee JavaScript 对象模型。另请注意,target.url 流变量是内置的读/写变量,可通过目标请求流访问。当我们使用 API 网址设置该变量时,Apigee 会对该网址执行后端调用。我们实质上重写了原始目标网址,也就是您在创建代理时指定的网址(例如,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
  7. 为政策命名,例如 target-rewrite。接受默认值并保存政策。
  8. 如果您在导航工具中选择代理端点 Preflow,将看到该政策已添加到该流中。
  9. 在导航工具中,选择目标端点 PreFlow 图标。
  10. 在导航工具中,将 JavaScript 政策拖动到流编辑器中目标端点的请求端。
  11. Save(保存)。
  12. 调用如下所示的 API,根据需要替换正确的组织名称和代理名称:
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>
</Javascript>

<JavaScript> 属性

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

以下属性特定于此政策。

属性 说明 默认 状态
timeLimit

指定允许脚本执行的最长时间(以毫秒为单位)。

注意:对于免费试用帐号,执行时间限制为 200 毫秒。

必需

下表介绍了所有政策父元素通用的特性:

特性 说明 默认 状态
name

政策的内部名称。name 属性的值可以包含字母、数字、空格、连字符、下划线和英文句点。此值不能超过 255 个字符。

(可选)使用 <DisplayName> 元素在管理界面代理编辑器中给政策添加不同的自然语言名称标签。

不适用 必需
continueOnError

设置为 false 可在政策失败时返回错误。这是大多数政策的预期行为。

设置为 true,即使在政策失败后,仍可以继续执行流。

可选
enabled

设置为 true 可强制执行政策。

设置为 false 可“关闭”政策。即使政策仍附加到某个流,也不会强制执行该政策。

可选
async

此属性已弃用。

已弃用

<DisplayName> 元素

除了用于 name 属性之外,还可以用于在管理界面代理编辑器中给政策添加不同的自然语言名称标签。

<DisplayName>Policy Display Name</DisplayName>
默认

不适用

如果省略此元素,则会使用政策的 name 属性的值。

状态 可选
类型 字符串

<IncludeURL> 元素

指定要作为使用 <ResourceURL> 元素指定的主要 JavaScript 文件的依赖项加载的 JavaScript 库文件。脚本将按政策中的列出顺序进行评估。您的代码可以使用 JavaScript 对象模型的对象、方法和属性。

使用附加 <IncludeURL> 元素添加多个 JavaScript 依赖项资源。

<IncludeURL>jsc://my-javascript-dependency.js</IncludeURL>
默认:
状态: 可选
类型: 字符串

示例

请参阅示例部分中的“基本示例”。

<Property> 元素

指定可在运行时从 JavaScript 代码访问的属性。

<Properties>
    <Property name="propName">propertyValue</Property>
</Properties>
默认:
状态: 可选
类型: 字符串

属性

属性 说明 默认 状态
名称

指定属性的名称。

必需。

示例

请参阅示例部分中的示例。

<ResourceURL> 元素

指定将在 API 流中执行的主要 JavaScript 文件。您可以在 API 代理范围(API 代理软件包的 /apiproxy/resources/jsc 下方或 API 代理编辑器导航工具窗格的“脚本”部分中)或组织或环境范围中存储此文件,以便在多个 API 代理中重复使用,如资源文件中所述。您的代码可以使用 JavaScript 对象模型的对象、方法和属性。

<ResourceURL>jsc://my-javascript.js</ResourceURL>
默认:
状态: 必需
类型: 字符串

示例

请参阅示例部分中的“基本示例”。

<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 的过程相同。如需了解详情,请参阅从 Apigee 到后端配置 TLS

如需详细了解如何创建 HTTP 客户端,请参阅在 JavaScript 中实施 HTTP 客户端

使用说明

JavaScript 政策不包含实际代码。相反,JavaScript 政策会引用 JavaScript“资源”,并在执行 JavaScript 的 API 流中定义步骤。您可以通过 Apigee 界面代理编辑器上传脚本,也可以在本地开发的 API 代理中将其包含在 /resources/jsc 目录中。

调试 JavaScript 政策代码

使用 print() 函数将调试信息输出到 Trace 工具中的事务输出面板。如需了解详情和示例,请参阅使用 JavaScript print() 语句进行调试。

要在 Trace 中查看 print 语句,请执行以下操作:

  1. 打开 Trace 工具并为包含 JavaScript 政策的代理启动跟踪会话。
  2. 调用代理。
  3. 在 Trace 工具中,点击从所有事务输出以打开输出面板。

  4. 您的 print 语句将显示在此面板中。

您可以使用 print() 函数将调试信息输出到 Trace 工具。此函数可直接通过 JavaScript 对象模型提供。如需了解详情,请参阅“使用 print() 语句调试 JavaScript”。

流变量

默认情况下,此政策不会填充任何变量;但是,您可以通过在上下文对象上调用方法,在 JavaScript 代码中设置(和获取)流变量。典型模式如下所示:

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

上下文对象是 Apigee JavaScript 对象模型的一部分。

错误参考信息

This section describes the fault codes and error messages that are returned and fault variables that are set by Apigee when this policy triggers an error. This information is important to know if you are developing fault rules to handle faults. To learn more, see What you need to know about policy errors and Handling faults.

Runtime errors

These errors can occur when the policy executes.

Fault code HTTP status Cause Fix
steps.javascript.ScriptExecutionFailed 500 The JavaScript policy can throw many different types of ScriptExecutionFailed errors. Commonly seen types of errors include RangeError, ReferenceError, SyntaxError, TypeError, and URIError.
steps.javascript.ScriptExecutionFailedLineNumber 500 An error occurred in the JavaScript code. See the fault string for details. N/A
steps.javascript.ScriptSecurityError 500 A security error occurred when the JavaScript executed. See the fault string for details. N/A

Deployment errors

These errors can occur when you deploy a proxy containing this policy.

Error name Cause Fix
InvalidResourceUrlFormat If the format of the resource URL specified within the <ResourceURL> or the <IncludeURL> element of the JavaScript policy is invalid, then the deployment of the API proxy fails.
InvalidResourceUrlReference If the <ResourceURL> or the <IncludeURL> elements refer to a JavaScript file that does not exist, then the deployment of the API proxy fails. The referenced source file must exist either the API proxy, environment, or organization level.
WrongResourceType This error occurs during deployment if the <ResourceURL> or the <IncludeURL> elements of the JavaScript policy refer to any resource type other than jsc (JavaScript file).
NoResourceURLOrSource The deployment of the JavaScript policy can fail with this error if the <ResourceURL> element is not declared or if the resource URL is not defined within this element. <ResourceURL> element is a mandatory element. Or, The <IncludeURL> element is declared but the resource URL is not defined within this element. The <IncludeURL> element is optional but if declared, the resource URL must be specified within the <IncludeURL> element.

Fault variables

These variables are set when this policy triggers an error at runtime. For more information, see What you need to know about policy errors.

Variables Where Example
fault.name="fault_name" fault_name is the name of the fault, as listed in the Runtime errors table above. The fault name is the last part of the fault code. fault.name Matches "ScriptExecutionFailed"
javascript.policy_name.failed policy_name is the user-specified name of the policy that threw the fault. javascript.JavaScript-1.failed = true

Example error response

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

Example fault rule

<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 社区中找到以下相关文章: