JavaScript 政策

<ph type="x-smartling-placeholder"></ph> 您正在查看 Apigee Edge 文档。
转到 Apigee X 文档
信息

内容

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

简介

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

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

JavaScript 政策让您可以指定要执行的 JavaScript 源文件,或者您可以使用 <Source> 元素直接在政策的配置中添加 JavaScript 代码。无论采用哪种方式,JavaScript 代码在执行政策关联的步骤时都会执行。对于源文件选项,源代码始终存储在代理软件包中的标准位置:apiproxy/resources/jsc。或者,您也可以将源代码存储在环境或组织级层的资源文件中。如需了解相关说明,请参阅资源文件。您还可以通过 Apigee 界面代理编辑器上传 JavaScript。

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

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

视频

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

示例

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

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

  1. 在 Edge 界面中,打开您在代理编辑器中创建的代理。
  2. 选择开发标签页。
  3. 从“新建”菜单中,选择新建脚本
  4. 在对话框中,选择 JavaScript 并为脚本命名,例如 js-example
  5. 将以下代码粘贴到代码编辑器中,并保存代理。需要注意的是 context 对象。在代理流中的任何位置,您都可以在 JavaScript 代码中使用此对象。它用于获取流特定常量、调用有用的 get/set 方法以及执行更多操作。该对象部分属于 Edge 的 JavaScript 对象模型。另请注意,target.url 流变量是内置的读/写变量,可通过目标请求流访问。当我们通过 API 网址设置该变量时 对该网址进行后端调用。我们实质上重写了原始目标网址,也就是您在创建代理时指定的网址(例如,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>

您可以在配置中添加 <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 毫秒。

必需

The following table describes attributes that are common to all policy parent elements:

Attribute Description Default Presence
name

The internal name of the policy. The value of the name attribute can contain letters, numbers, spaces, hyphens, underscores, and periods. This value cannot exceed 255 characters.

Optionally, use the <DisplayName> element to label the policy in the management UI proxy editor with a different, natural-language name.

N/A Required
continueOnError

Set to false to return an error when a policy fails. This is expected behavior for most policies.

Set to true to have flow execution continue even after a policy fails.

false Optional
enabled

Set to true to enforce the policy.

Set to false to turn off the policy. The policy will not be enforced even if it remains attached to a flow.

true Optional
async

This attribute is deprecated.

false Deprecated

<DisplayName> element

Use in addition to the name attribute to label the policy in the management UI proxy editor with a different, natural-language name.

<DisplayName>Policy Display Name</DisplayName>
Default

N/A

If you omit this element, the value of the policy's name attribute is used.

Presence Optional
Type String

<IncludeURL> 元素

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

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

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

示例

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

<Property> 元素

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

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

特性

属性 说明 默认 状态
name

指定属性的名称。

不适用 必需。

示例

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

<ResourceURL> 元素

指定将在 API 流中执行的主要 JavaScript 文件。您可以在 API 代理范围(API 代理软件包的 /apiproxy/resources/jsc 下方或 API 代理编辑器导航工具窗格的“脚本”部分中)或组织或环境范围中存储此文件,以便在多个 API 代理中重复使用,如资源文件中所述。您的代码可以使用 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 政策不包含实际代码。相反,JavaScript 政策会引用 JavaScript“资源”,并在执行 JavaScript 的 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 Edge JavaScript 对象模型的一部分。

错误参考信息

本部分介绍返回的错误代码、错误消息以及故障变量 在此政策触发错误时由 Edge 设置的值。在开发故障规则以处理故障时,请务必了解此信息。如需了解详情,请参阅您需要了解的有关政策错误的信息处理故障

运行时错误

政策执行时可能会发生这些错误。

故障代码 HTTP 状态 原因 修复
steps.javascript.ScriptExecutionFailed 500 JavaScript 政策可能会抛出许多不同类型的 ScriptExecutionFailed 错误。常见的错误类型包括:RangeErrorReferenceErrorSyntaxErrorTypeErrorURIError
steps.javascript.ScriptExecutionFailedLineNumber 500 JavaScript 代码中出现错误。请参阅故障字符串了解详情。
steps.javascript.ScriptSecurityError 500 执行 JavaScript 时出现安全错误。请参阅故障字符串了解详情。

部署错误

在您部署包含此政策的代理时,可能会发生这些错误。

错误名称 原因 修复
InvalidResourceUrlFormat 如果 JavaScript 政策的 <ResourceURL><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 社区中找到以下相关文章: