CloudFront Functions 事件结构 - Amazon CloudFront
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 Amazon Web Services 服务入门

CloudFront Functions 事件结构

CloudFront Functions 在运行函数时将 event 对象作为输入传递给函数代码。当您测试函数时,可以创建 event 对象并将其传递至您的函数。创建用于测试函数的 event 对象时,您可以省略 context 对象中的 distributionDomainNamedistributionIdrequestId 字段。此外,请确保标头的名称为小写字母,在生产环境中 CloudFront Functions 传递给您的函数的 event 对象中情况总是如此。

下面显示了此事件对象的结构概述。有关详细信息,请参阅以下主题。

{ "version": "1.0", "context": { <context object> }, "viewer": { <viewer object> }, "request": { <request object> }, "response": { <response object> } }

版本字段

version 字段包含一个字符串,用于指定 CloudFront Functions 事件对象的版本。当前版本为 1.0

Context 对象

context 对象包含有关事件的上下文信息。其中包括以下字段:

distributionDomainName

与事件关联的分配的 CloudFront 域名(例如 d111111abcdef8.cloudfront.net)。

distributionId

与事件关联的分配的 ID(例如 EDFDVBD6EXAMPLE)。

eventType

事件类型,viewer-requestviewer-response

requestId

唯一标识 CloudFront 请求(及其关联响应)的字符串。

查看器对象

viewer 对象包含一个 ip 字段,其值为发送请求的查看器(客户端)的 IP 地址。如果查看器请求来自 HTTP 代理或负载均衡器,则值为该代理或负载均衡器的 IP 地址。

请求对象

request 对象包含查看器至 CloudFront HTTP 请求的表示形式。在传递至您的函数的 event 对象中,request 对象代表 CloudFront 从查看器中接收的实际请求。

如果您的函数代码将 request 对象返回到 CloudFront,则它必须使用相同的结构。

request 对象包含以下字段:

method

请求中的 HTTP 方法。如果您的函数代码返回 request,则无法修改此字段。这是 request 对象中唯一的只读字段。

uri

所请求对象的相对路径。如果您的函数修改了 uri 值,请记住以下事项:

  • 新的 uri 值必须以正斜杠(/)开头。

  • 如果某个函数更改 uri 值,则它会更改查看器请求的对象。

  • 如果某个函数更改 uri 值,它不会更改请求或源请求发送到的源的缓存行为。

querystring

表示请求中的查询字符串的对象。如果请求中没有包括查询字符串,则 request 对象仍然包括空的 querystring 对象。

querystring 对象为请求中的每个查询字符串参数包含一个字段。

headers

表示请求中的 HTTP 标头的对象。如果请求包含任何 Cookie 标头,则这些标头不属于 headers 对象的一部分。Cookies 在 cookies 对象中单独表示。

headers 对象为请求中的每个标头包含一个字段。标头名称在事件对象中转换为小写,当您的函数代码添加它们时,标头名称必须为小写。当 CloudFront 函数将事件对象转换回 HTTP 请求时,标头名称中每个单词的第一个字母都会大写。单词由连字符 (-) 分隔。例如,如果您的函数代码添加了名为 example-header-name 的标头,CloudFront 会将其转换为 HTTP 请求中的 Example-Header-Name

cookies

表示请求中的 Cookies 的对象(Cookie 标头)。

cookies 对象为请求中的每个 Cookie 包含一个字段。

有关查询字符串、标头和 Cookies 结构的更多信息,请参阅 查询字符串、标头和 Cookie 结构

有关示例 event 对象,请参阅 示例事件

响应对象

response 对象包含 CloudFront 至查看器 HTTP 响应的表示形式。在传递至您的函数的 event 对象中,response 对象表示 CloudFront 对查看器请求的实际响应。

如果您的函数代码返回一个 response 对象,它必须使用这个相同的结构。

response 对象包含以下字段:

statusCode

响应的 HTTP 状态代码。该值是一个整数,不是字符串。

如果函数与查看器响应事件类型关联,则函数代码无法更改它收到的 statusCode。如果函数与查看器请求事件类型关联并且生成 HTTP 响应,则函数代码可以设置 statusCode

statusDescription

响应的 HTTP 状态描述。如果函数代码生成响应,则此字段为可选字段。

headers

表示响应中的 HTTP 标头的对象。如果响应包含任何 Set-Cookie 标头,则这些标头不属于 headers 对象的一部分。Cookies 在 cookies 对象中单独表示。

headers 对象为响应中的每个标头包含一个字段。标头名称在事件对象中转换为小写,当您的函数代码添加它们时,标头名称必须为小写。当 CloudFront 函数将事件对象转换回 HTTP 响应时,标头名称中每个单词的第一个字母都会大写。单词由连字符 (-) 分隔。例如,如果您的函数代码添加了名为 example-header-name 的标头,CloudFront 会将其转换为 HTTP 响应中的 Example-Header-Name

cookies

表示响应中的 Cookies 的对象(Set-Cookie 标头)。

cookies 对象为响应中的每个 Cookie 包含一个字段。

有关标头和 Cookies 结构的更多信息,请参阅 查询字符串、标头和 Cookie 结构

有关示例 event 对象,请参阅 示例事件

requestresponse 对象中的查询字符串、标头和 Cookies 共享同一个结构。每个查询字符串、标头或 Cookie 都是父项 querystringheaderscookies 对象内的唯一字段。字段名称是查询字符串、标头或 Cookie 的名称。每个字段都包含一个 value 属性,并带有查询字符串、标头或 Cookie 的值。

仅对于标头,标头名称在事件对象中转换为小写,当您的函数代码添加它们时,标头名称必须为小写。当 CloudFront 函数将事件对象转换回 HTTP 请求或响应时,标头名称中每个单词的第一个字母都会大写。单词由连字符 (-) 分隔。例如,如果您的函数代码添加了名为 example-header-name 的标头,CloudFront 会将其转换为 HTTP 请求或响应中的 Example-Header-Name

例如,考虑 HTTP 请求中的以下 Host 标头:

Host: video.example.com

该标头在 request 对象中表示如下:

"headers": { "host": { "value": "video.example.com" } }

要访问函数代码中的 Host 标头,请使用如下代码:

var request = event.request; var host = request.headers.host.value;

要在函数代码中添加或修改标头,请使用如下代码(此代码添加了一个名为 X-Custom-Header 且带有值 example value 的标头):

var request = event.request; request.headers['x-custom-header'] = {value: 'example value'};

重复的查询字符串、标头和 Cookies(multiValue 数组)

HTTP 请求或响应可以包含多个具有相同名称的查询字符串、标头或 Cookie。在这种情况下,重复的查询字符串、标头或 Cookie 会折叠为 requestresponse 对象中的一个字段,但此字段包含名为 multiValue 的额外属性。multiValue 属性包含一个数组,其中包含每个重复查询字符串、标头或 Cookies 的值。

例如,考虑带有以下 Accept 标头的 HTTP 请求:

Accept: application/json Accept: application/xml Accept: text/html

这些标头在 request 对象中表示如下:

"headers": { "accept": { "value": "application/json", "multiValue": [ { "value": "application/json" }, { "value": "application/xml" }, { "value": "text/html" } ] } }

请注意,第一个标头值(在本例中为 application/json)在 valuemultiValue 属性中重复。这样一来,您可以通过循环 multiValue 数组来访问全部值。

如果您的函数代码使用 multiValue 数组修改查询字符串、标头或 Cookie,CloudFront Functions 将使用以下规则来应用更改:

  1. 如果 multiValue 数组存在并进行了任何修改,则应用该修改。value 属性中的第一个元素将被忽略。

  2. 否则,将应用对 value 属性的任何修改,后续值(如果存在)保持不变。

仅当 HTTP 请求或响应中包含重复的查询字符串、标头或具有相同名称的 Cookie 时,才使用 multiValue 属性,如前面的示例所示。但是,如果单个查询字符串、标头或 Cookie 中有多个值,则不使用 multiValue 属性。

例如,假设一个请求包含一个含有三个值的 Accept 标头,如以下示例所示:

Accept: application/json, application/xml, text/html

该标头在 request 对象中表示如下:

"headers": { "accept": { "value": "application/json, application/xml, text/html" } }

在 HTTP 响应的 Set-Cookie 标头中,标头包含 Cookie 的名称-值对以及可选的一组用分号分隔的属性。例如:

Set-Cookie: cookie1=val1; Secure; Path=/; Domain=example.com; Expires=Wed, 05 Apr 2021 07:28:00 GMT"

response 对象中,这些属性在 Cookie 字段的 attributes 属性中表示。例如,前面的 Set-Cookie 标头表示如下:

"cookie1": { "value": "val1", "attributes": "Secure; Path=/; Domain=example.com; Expires=Wed, 05 Apr 2021 07:28:00 GMT" }

示例事件

以下示例显示了一个完整的 event 对象。

注意

event 对象是函数的输入。您的函数只返回 requestresponse 对象,而不返回完整的 event 对象。

{ "version": "1.0", "context": { "distributionDomainName": "d111111abcdef8.cloudfront.net", "distributionId": "EDFDVBD6EXAMPLE", "eventType": "viewer-response", "requestId": "EXAMPLEntjQpEXAMPLE_SG5Z-EXAMPLEPmPfEXAMPLEu3EqEXAMPLE==" }, "viewer": { "ip": "198.51.100.11" }, "request": { "method": "GET", "uri": "/media/index.mpd", "querystring": { "ID": { "value": "42" }, "Exp": { "value": "1619740800" }, "TTL": { "value": "1440" }, "NoValue": { "value": "" }, "querymv": { "value": "val1", "multiValue": [ { "value": "val1" }, { "value": "val2,val3" } ] } }, "headers": { "host": { "value": "video.example.com" }, "user-agent": { "value": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Firefox/83.0" }, "accept": { "value": "application/json", "multiValue": [ { "value": "application/json" }, { "value": "application/xml" }, { "value": "text/html" } ] }, "accept-language": { "value": "en-GB,en;q=0.5" }, "accept-encoding": { "value": "gzip, deflate, br" }, "origin": { "value": "https://website.example.com" }, "referer": { "value": "https://website.example.com/videos/12345678?action=play" }, "cloudfront-viewer-country": { "value": "GB" } }, "cookies": { "Cookie1": { "value": "value1" }, "Cookie2": { "value": "value2" }, "cookie_consent": { "value": "true" }, "cookiemv": { "value": "value3", "multiValue": [ { "value": "value3" }, { "value": "value4" } ] } } }, "response": { "statusCode": 200, "statusDescription": "OK", "headers": { "date": { "value": "Mon, 04 Apr 2021 18:57:56 GMT" }, "server": { "value": "gunicorn/19.9.0" }, "access-control-allow-origin": { "value": "*" }, "access-control-allow-credentials": { "value": "true" }, "content-type": { "value": "application/json" }, "content-length": { "value": "701" } }, "cookies": { "ID": { "value": "id1234", "attributes": "Expires=Wed, 05 Apr 2021 07:28:00 GMT" }, "Cookie1": { "value": "val1", "attributes": "Secure; Path=/; Domain=example.com; Expires=Wed, 05 Apr 2021 07:28:00 GMT", "multiValue": [ { "value": "val1", "attributes": "Secure; Path=/; Domain=example.com; Expires=Wed, 05 Apr 2021 07:28:00 GMT" }, { "value": "val2", "attributes": "Path=/cat; Domain=example.com; Expires=Wed, 10 Jan 2021 07:28:00 GMT" } ] } } } }