本页面适用于 Apigee 和 Apigee Hybrid。
查看 Apigee Edge 文档。
内容
此政策允许您添加在 API 代理流上下文中执行的自定义 JavaScript 代码。在自定义 JavaScript 代码中,您可以使用 Apigee JavaScript 对象模型的对象、方法和属性。对象模型让您可在代理流上下文中获取、设置和移除变量。您还可以使用随对象模型提供的基本加密函数。
此政策是一项可扩展政策,使用此政策可能会影响费用或使用情况,具体取决于您的 Apigee 许可。如需了解政策类型和使用情况影响,请参阅政策类型。
关于
JavaScript 政策有许多用例。例如,您可以获取和设置流变量,执行自定义逻辑并执行故障处理,从请求或响应中提取数据,动态编辑后端目标网址,等等。该政策让您可实施任何其他标准 Apigee 政策未涵盖的自定义行为。实际上,您可以使用 JavaScript 政策来实现其他政策实施的许多行为,如 AssignMessage 和 ExtractVariable。
对于 JavaScript 政策,我们不建议的用例是日志记录。MessageLogging 政策更适合记录到 Splunk,Sumo 和 Loggly 等第三方日志记录平台,并且您可通过在 PostClientFlow 中执行 MessageLogging 政策来提高 API 代理性能。PostClientFlow 在将响应发送回客户端后执行。
JavaScript 政策让您可以指定要执行的 JavaScript 源文件,或者您可以使用 <Source>
元素直接在政策的配置中添加 JavaScript 代码。无论采用哪种方式,JavaScript 代码在执行政策关联的步骤时都会执行。对于源文件选项,源代码始终存储在代理软件包中的标准位置:apiproxy/resources/jsc
。或者,您也可以将源代码存储在环境或组织级层的资源文件中。如需了解相关说明,请参阅资源文件。您还可以通过 Apigee 界面代理编辑器上传 JavaScript。
JavaScript 源文件必须始终具有 .js
扩展名。
Apigee 支持在 Rhino JavaScript 引擎 1.7.13 上运行的 JavaScript。
视频
观看短视频,了解如何使用 JavaScript 政策创建自定义政策扩展程序。
示例
重写目标网址
下面是一个常见的用例:从请求正文中提取数据,将其存储在流变量中,并在代理流的其他位置使用该流变量。假设您有一个应用,用户可以在 HTML 表单中输入其名称并提交该名称。您希望 API 代理提取表单数据,并将其动态添加到用于调用后端服务的网址。如何在 JavsScript 政策中执行此操作?
- 在 Apigee 界面中,打开您在代理编辑器中创建的代理。
- 选择开发标签页。
- 从“新建”菜单中,选择新建脚本。
- 在对话框中,选择 JavaScript 并为脚本命名,例如
js-example
。 - 将以下代码粘贴到代码编辑器中,并保存代理。需要注意的是
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); }
- 从“新建政策”菜单中,选择 JavaScript。
- 为政策命名,例如
target-rewrite
。接受默认值并保存政策。 - 如果您在导航工具中选择代理端点 Preflow,将看到该政策已添加到该流中。
- 在导航工具中,选择目标端点 PreFlow 图标。
- 在导航工具中,将 JavaScript 政策拖动到流编辑器中目标端点的请求端。
- 保存。
- 调用如下所示的 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 标注中使用的错误处理方法的示例并展开讨论,请参阅根据 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">
以下属性特定于此政策。
属性 | 说明 | 默认 | Presence |
---|---|---|---|
timeLimit |
指定允许脚本执行的最长时间(以毫秒为单位)。例如,如果超出 200 毫秒的限制,则政策会引发以下错误: |
不适用 | 必需 |
下表介绍了所有政策父元素通用的特性:
属性 | 说明 | 默认 | Presence |
---|---|---|---|
name |
政策的内部名称。 (可选)使用 |
不适用 | 必需 |
continueOnError |
设置为 设置为 |
false | 可选 |
enabled |
设置为 设为 |
true | 可选 |
async |
此特性已弃用。 |
false | 已弃用 |
<DisplayName> 元素
用于在 name
属性之外在管理界面代理编辑器中给政策添加不同的自然语言名称标签。
<DisplayName>Policy Display Name</DisplayName>
默认 |
不适用 如果省略此元素,则会使用政策的 |
---|---|
Presence | 可选 |
类型 | 字符串 |
<IncludeURL> 元素
指定要作为使用 <ResourceURL>
或 <Source>
元素指定的主要 JavaScript 文件的依赖项加载的 JavaScript 库文件。脚本将按政策中的列出顺序进行评估。您的代码可以使用 JavaScript 对象模型的对象、方法和属性。
使用附加 <IncludeURL>
元素添加多个 JavaScript 依赖项资源。
<IncludeURL>jsc://my-javascript-dependency.js</IncludeURL>
默认: | 无 |
状态: | 可选 |
类型: | 字符串 |
示例
请参阅示例部分中的“基本示例”。
<Property> 元素
指定可在运行时从 JavaScript 代码访问的属性。
<Properties> <Property name="propName">propertyValue</Property> </Properties>
默认: | 无 |
状态: | 可选 |
类型: | 字符串 |
属性
属性 | 说明 | 默认 | Presence |
---|---|---|---|
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 政策代码
使用 print()
函数将调试信息输出到调试工具中的事务输出面板。如需了解详情和示例,请参阅使用 JavaScript print()
语句进行调试。
要在调试工具中查看 print 语句,请执行以下操作:
- 打开调试工具并为包含 JavaScript 政策的代理启动跟踪会话。
- 调用代理。
- 在调试工具中,点击从所有事务输出 (Output from all Transactions) 以打开输出面板。
- 您的 print 语句将显示在此面板中。
您可以使用 print()
函数将调试信息输出到调试工具。此函数可直接通过 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. |
build |
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. |
build |
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. |
build |
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). |
build |
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. |
build |
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 社区中找到以下相关文章: