

# 边缘函数的限制
<a name="edge-functions-restrictions"></a>

以下主题描述了适用于 CloudFront Functions 和 Lambda@Edge 的限制。一些限制适用于所有边缘函数，而另一些限制仅适用于 CloudFront Functions 或 Lambda@Edge。

每个主题都提供了有关您在使用 CloudFront 开发和部署边缘函数时应考虑的限制和约束的详细信息。

了解这些限制有助于确保边缘函数按预期运行并符合支持的功能。

**Topics**
+ [

# 所有边缘函数的限制
](edge-function-restrictions-all.md)
+ [

# 对 CloudFront Functions 的限制
](cloudfront-function-restrictions.md)
+ [

# 对 Lambda@Edge 的限制
](lambda-at-edge-function-restrictions.md)

有关配额（以前被称为限制）的更多信息，请参阅 [CloudFront Functions 的配额](cloudfront-limits.md#limits-functions) 和 [有关 Lambda@Edge 的配额](cloudfront-limits.md#limits-lambda-at-edge)。

# 所有边缘函数的限制
<a name="edge-function-restrictions-all"></a>

以下限制适用于所有边缘函数，包括 CloudFront Functions 和 Lambda@Edge。

**Topics**
+ [

## Amazon Web Services 账户所有权
](#function-restrictions-account-ownership)
+ [

## 组合 CloudFront Functions 与 Lambda@Edge
](#function-restrictions-combining-functions)
+ [

## HTTP 状态代码
](#function-restrictions-status-codes)
+ [

## HTTP 标头
](#function-restrictions-headers)
+ [

## 查询字符串
](#function-restrictions-query-strings)
+ [

## URI
](#function-restrictions-uri)
+ [

## URI、查询字符串和标头编码
](#function-restrictions-encoding)
+ [

## Microsoft Smooth Streaming
](#function-restrictions-microsoft-smooth-streaming)
+ [

## 标签
](#function-restrictions-tagging)

## Amazon Web Services 账户所有权
<a name="function-restrictions-account-ownership"></a>

要将边缘函数与 CloudFront 分配相关联，该函数和分配必须属于相同的 Amazon Web Services 账户。

## 组合 CloudFront Functions 与 Lambda@Edge
<a name="function-restrictions-combining-functions"></a>

对于给定缓存行为，将适用以下限制将适用：
+ 每个事件类型（查看器请求、源请求、源响应和查看器响应）只能有一个边缘函数关联。
+ 您不能在查看器事件（查看器请求和查看器响应）中组合 CloudFront Functions 和 Lambda@Edge。

允许使用边缘函数的所有其他组合。下表介绍了允许的组合。

[\[See the AWS documentation website for more details\]](http://docs.amazonaws.cn/AmazonCloudFront/latest/DeveloperGuide/edge-function-restrictions-all.html)

## HTTP 状态代码
<a name="function-restrictions-status-codes"></a>

如果源返回 400 或更高的 HTTP 状态代码，则 CloudFront 不会对查看器响应事件调用边缘函数。

用于源响应事件的 Lambda@Edge 函数被调用于*全部*源响应，包括源返回 400 或更高的 HTTP 状态代码。有关更多信息，请参阅 [更新源响应触发器中的 HTTP 响应](lambda-generating-http-responses.md#lambda-updating-http-responses)。

## HTTP 标头
<a name="function-restrictions-headers"></a>

不允许使用某些 HTTP 标头，这意味着这些标头不会向边缘函数公开，并且函数无法添加它们。其他标头是只读的，这意味着函数可以读取它们，但不能添加、修改或删除它们。

**Topics**
+ [

### 不允许使用的标头
](#function-restrictions-disallowed-headers)
+ [

### 只读标头
](#function-restrictions-read-only-headers)

### 不允许使用的标头
<a name="function-restrictions-disallowed-headers"></a>

以下 HTTP 标头不会向边缘函数公开，并且函数无法添加它们。如果您的函数添加这些标头的其中之一，则请求将无法通过 CloudFront 验证，并且 CloudFront 会将 HTTP 状态代码 502（无效网关）返回给查看器。
+ `Connection` 
+ `Expect`
+ `Keep-Alive`
+ `Proxy-Authenticate`
+ `Proxy-Authorization`
+ `Proxy-Connection`
+ `Trailer`
+ `Upgrade`
+ `X-Accel-Buffering`
+ `X-Accel-Charset`
+ `X-Accel-Limit-Rate`
+ `X-Accel-Redirect`
+ `X-Amz-Cf-*`
+ `X-Amzn-Auth`
+ `X-Amzn-Cf-Billing`
+ `X-Amzn-Cf-Id`
+ `X-Amzn-Cf-Xff`
+ `X-Amzn-Errortype`
+ `X-Amzn-Fle-Profile`
+ `X-Amzn-Header-Count`
+ `X-Amzn-Header-Order`
+ `X-Amzn-Lambda-Integration-Tag`
+ `X-Amzn-RequestId`
+ `X-Cache`
+ `X-Edge-*`
+ `X-Forwarded-Proto`
+ `X-Real-IP`

### 只读标头
<a name="function-restrictions-read-only-headers"></a>

以下标头是只读的。您的函数可以读取这些标头，并将其用作函数逻辑输入，但无法更改这些值。如果您的函数添加或编辑一个只读标头，请求将无法通过 CloudFront 验证，并且 CloudFront 将 HTTP 状态代码 502（无效网关）返回到查看器。

#### 查看器请求事件中的只读标头
<a name="function-restrictions-read-only-headers-viewer-request"></a>

以下标头在查看器请求事件中为只读标头。
+ `Content-Length`
+ `Host`
+ `Transfer-Encoding`
+ `Via`

#### 源请求事件中的只读标头（仅限 Lambda@Edge）
<a name="function-restrictions-read-only-headers-origin-request"></a>

以下标头在源请求事件中是只读的，它们仅存在于 Lambda@Edge 中。
+ `Accept-Encoding`
+ `Content-Length`
+ `If-Modified-Since`
+ `If-None-Match`
+ `If-Range`
+ `If-Unmodified-Since`
+ `Transfer-Encoding`
+ `Via`

#### 源响应事件中的只读标头（仅限 Lambda@Edge）
<a name="function-restrictions-read-only-headers-origin-response"></a>

以下标头在源响应事件中是只读的，它们仅存在于 Lambda@Edge 中。
+ `Transfer-Encoding`
+ `Via`

#### 查看器响应事件中的只读标头
<a name="function-restrictions-read-only-headers-viewer-response"></a>

以下标头在查看器响应事件中为只读标头（对于 CloudFront Functions 和 Lambda@Edge）
+ `Warning`
+ `Via`

以下标头在查看器响应事件中为只读标头（对于 Lambda@Edge）。
+ `Content-Length`
+ `Content-Encoding`
+ `Transfer-Encoding`

## 查询字符串
<a name="function-restrictions-query-strings"></a>

以下限制适用于在请求 URI 中读取、更新或创建查询字符串的函数。
+ （仅限 Lambda@Edge）要访问源请求或源响应函数中的查询字符串，您的缓存策略或源请求策略必须针对**查询字符串**设置为 **All**。
+ 函数可以为查看器请求和源请求事件创建或更新查询字符串（源请求事件仅在 Lambda@Edge 中存在）。
+ 函数可以为源响应和查看器响应事件读取查询字符串，但不能创建或更新查询字符串（源响应事件仅在 Lambda@Edge 中存在）。
+ 如果函数创建或更新查询字符串，则具有以下限制：
  + 查询字符串不能包含空格、控制字符或片段标识符 (`#`)。
  + URI（包括查询字符串）的总大小必须小于 8192 个字符。
  + 建议您对 URI 和查询字符串使用百分号编码。有关更多信息，请参阅 [URI、查询字符串和标头编码](#function-restrictions-encoding)。

## URI
<a name="function-restrictions-uri"></a>

如果某个函数更改请求的 URI，则这样不会更改该请求或该请求转发到的源的缓存行为。

URI（包括查询字符串）的总大小必须小于 8192 个字符。

## URI、查询字符串和标头编码
<a name="function-restrictions-encoding"></a>

传递给边缘函数的 URI、查询字符串和标头的值是使用 UTF-8 编码的。函数应该对其返回的 URI、查询字符串和标头值使用 UTF-8 编码。百分号编码与 UTF-8 编码兼容。

下面的列表解释了 CloudFront 如何处理 URI、查询字符串和标头的编码：
+ 如果请求中的值是 UTF-8 编码，则 CloudFront 会将值转发给您的函数，而不会更改它们。
+ 如果请求中的值为 [ISO-8859-1 编码](https://en.wikipedia.org/wiki/ISO/IEC_8859-1)，CloudFront 会将值转换为 UTF-8 编码，然后再将值转发给您的函数。
+ 如果请求中的值使用任何其他字符编码方式进行编码，则 CloudFront 会假定它们是 ISO-8859-1 编码，并尝试从 ISO-8859-1 编码转换为 UTF-8 编码。
**重要**  
转换后字符可能是原始请求中的值的不准确解释。这可能会导致您的函数或源生成意外结果。

CloudFront 转发到源的 URI、查询字符串和标头的值取决于函数是否更改了值：
+ 如果函数没有更改 URI、查询字符串或标头，CloudFront 会将它在请求中收到的值转发到源。
+ 如果函数更改了 URI、查询字符串或标头，则 CloudFront 转发 UTF-8 编码的值。

## Microsoft Smooth Streaming
<a name="function-restrictions-microsoft-smooth-streaming"></a>

您无法将边缘函数与用于流式传输媒体文件（已转码为 Microsoft Smooth Streaming 格式）的 CloudFront 分配一起使用。

## 标签
<a name="function-restrictions-tagging"></a>

您无法将标签添加到边缘函数。有关在 CloudFront 中进行标记的更多信息，请参阅[标记分配](tagging.md)。

# 对 CloudFront Functions 的限制
<a name="cloudfront-function-restrictions"></a>

以下限制仅适用于 CloudFront Functions。

**Contents**
+ [

## 日志
](#cloudfront-function-restrictions-logs)
+ [

## 请求正文
](#cloudfront-function-restrictions-request-body)
+ [

## 将临时凭证与 CloudFront KeyValueStore API 结合使用
](#regional-endpoint-for-key-value-store)
+ [

## 运行时
](#cloudfront-function-runtime-restrictions)
+ [

## 计算利用率
](#cloudfront-function-restrictions-compute-utilization)

有关配额（以前称为限制）的更多信息，请参阅[CloudFront Functions 的配额](cloudfront-limits.md#limits-functions)。

## 日志
<a name="cloudfront-function-restrictions-logs"></a>

CloudFront Functions 中的函数日志被截断为 10 KB。

## 请求正文
<a name="cloudfront-function-restrictions-request-body"></a>

CloudFront Functions 无法访问 HTTP 请求的正文。

## 将临时凭证与 CloudFront KeyValueStore API 结合使用
<a name="regional-endpoint-for-key-value-store"></a>

您可以使用 Amazon Security Token Service（Amazon STS）生成临时安全凭证（也称为*会话令牌*）。会话令牌支持您临时代入 Amazon Identity and Access Management（IAM）角色，以便您可以访问 Amazon Web Services 服务。

要调用 [CloudFront KeyValueStore API](https://docs.amazonaws.cn/cloudfront/latest/APIReference/API_Operations_Amazon_CloudFront_KeyValueStore.html)，请使用 Amazon STS 中的*区域* 端点来返回*版本 2* 会话令牌。如果您将*全局* 端点用于 Amazon STS（`sts.amazonaws.com`），Amazon STS 将生成*版本 1* 会话令牌，而签名版本 4A（SigV4A）不支持该令牌。因此，您将会收到身份验证错误。

要调用 CloudFront KeyValueStore API，可以使用以下选项：

**Amazon CLI 和 Amazon SDK**  
可以将 Amazon CLI 或 Amazon SDK 配置为使用区域 Amazon STS 端点。有关更多信息，请参阅《Amazon SDK 和工具参考指南》**中的 [Amazon STS Regionalized endpoints](https://docs.amazonaws.cn/sdkref/latest/guide/feature-sts-regionalized-endpoints.html)。  
有关可用 Amazon STS 端点的更多信息，请参阅《IAM 用户指南》**中的[区域和端点](https://docs.amazonaws.cn/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html#id_credentials_region-endpoints)。

**SAML**  
可以将 SAML 配置为使用区域 Amazon STS 端点。有关更多信息，请参阅 [How to use regional SAML endpoints for failover](https://www.amazonaws.cn/blogs/security/how-to-use-regional-saml-endpoints-for-failover/) 博客文章。

**`SetSecurityTokenServicePreferences` API**  
您可以为 Amazon STS 配置全局端点来返回版本 2 会话令牌，而不是使用区域 Amazon STS 端点。为此，请使用 [SetSecurityTokenServicePreferences](https://docs.amazonaws.cn/IAM/latest/APIReference/API_SetSecurityTokenServicePreferences.html) API 操作来配置您的 Amazon Web Services 账户。  

**Example 示例：IAM CLI 命令**  

```
aws iam set-security-token-service-preferences --global-endpoint-token-version v2Token
```
我们建议您使用 Amazon STS 区域端点来代替此选项。区域端点可提供更高的可用性和失效转移方案。

**自定义身份提供者**  
如果您使用的是执行联合身份验证并代入角色的自定义身份提供者，请使用负责生成会话令牌的父身份提供者系统的先前选项之一。

## 运行时
<a name="cloudfront-function-runtime-restrictions"></a>

CloudFront Functions 运行时环境不支持动态代码评估，并且该环境限制了对网络、文件系统、环境变量和计时器的访问。有关更多信息，请参阅 [受限功能](functions-javascript-runtime-10.md#writing-functions-javascript-features-restricted-features)。

**注意**  
要使用 CloudFront keyValueStore，您的 CloudFront 函数必须使用 [JavaScript 运行时 2.0](functions-javascript-runtime-20.md)。

## 计算利用率
<a name="cloudfront-function-restrictions-compute-utilization"></a>

CloudFront Functions 对运行时间有限制，测量方式为*计算利用率*。计算利用率是介于 0 到 100 之间的数字，表示函数运行所花费的时间占最大允许时间的百分比。例如，计算利用率为 35 表示函数在最大允许时间的 35% 内完成。

当您[测试函数](test-function.md)时，您可以在测试事件的输出中看到计算利用率值。对于生产函数，您可以在 [CloudFront 控制台中的监控页面](https://console.amazonaws.cn/cloudfront/v4/home?#/monitoring)或在 CloudWatch 中查看[计算利用率指标](viewing-cloudfront-metrics.md#monitoring-console.cloudfront-functions)。

# 对 Lambda@Edge 的限制
<a name="lambda-at-edge-function-restrictions"></a>

以下限制仅适用于 Lambda@Edge。

**Contents**
+ [

## DNS 解析
](#lambda-at-edge-restrictions-dns)
+ [

## HTTP 状态代码
](#lambda-at-edge-restrictions-status-codes)
+ [

## Lambda 函数版本
](#lambda-at-edge-restrictions-version)
+ [

## Lambda 区域
](#lambda-at-edge-restrictions-region)
+ [

## Lambda 角色权限
](#lambda-at-edge-restrictions-role-permissions)
+ [

## Lambda 功能
](#lambda-at-edge-restrictions-features)
+ [

## 支持的运行时
](#lambda-at-edge-restrictions-runtime)
+ [

## CloudFront 标头
](#lambda-at-edge-restrictions-cloudfront-headers)
+ [

## 具有 Include Body（包含正文）选项的请求正文的限制
](#lambda-at-edge-restrictions-request-body)
+ [

## 响应超时和保持连接超时（仅自定义源）
](#timeout-for-lambda-edge-functions)

有关 配额的信息，请参阅 [有关 Lambda@Edge 的配额](cloudfront-limits.md#limits-lambda-at-edge)。

## DNS 解析
<a name="lambda-at-edge-restrictions-dns"></a>

CloudFront 会先对源域名执行 DNS 解析，*然后* 再执行源请求 Lambda@Edge 函数。如果您的域的 DNS 服务出现问题，并且 CloudFront 无法解析域名以获取 IP 地址，将不会调用您的 Lambda@Edge 函数。CloudFront 会将 [HTTP 状态代码 502（无效网关）](http-502-bad-gateway.md)返回到客户端。有关更多信息，请参阅 [DNS 错误（`NonS3OriginDnsError`）](http-502-bad-gateway.md#http-502-dns-error)。

如果您的函数逻辑修改了源域名，则在函数执行完毕后，CloudFront 将对已更新的域名执行另一次 DNS 解析。

有关管理 DNS 故障转移的更多信息，请参阅《Amazon Route 53 开发人员指南》**中的[配置 DNS 故障转移](https://docs.amazonaws.cn/Route53/latest/DeveloperGuide/dns-failover-configuring.html)。

## HTTP 状态代码
<a name="lambda-at-edge-restrictions-status-codes"></a>

查看器响应事件的 Lambda@Edge 函数无法修改响应的 HTTP 状态代码，无论响应是来自源还是 CloudFront 缓存。

## Lambda 函数版本
<a name="lambda-at-edge-restrictions-version"></a>

您必须使用带编号的 Lambda 函数，而不是 `$LATEST` 或别名。

## Lambda 区域
<a name="lambda-at-edge-restrictions-region"></a>

Lambda 函数必须位于美国东部（弗吉尼亚州北部）区域。

## Lambda 角色权限
<a name="lambda-at-edge-restrictions-role-permissions"></a>

与 Lambda 函数关联的 IAM 执行角色必须由服务委托人 `lambda.amazonaws.com` 和 `edgelambda.amazonaws.com` 担任。有关更多信息，请参阅 [设置 Lambda@Edge 的 IAM 权限和角色](lambda-edge-permissions.md)。

## Lambda 功能
<a name="lambda-at-edge-restrictions-features"></a>

Lambda@Edge 不支持以下 Lambda 功能：
+ **自动**（默认设置）以外的 [Lambda 运行时管理配置](https://docs.amazonaws.cn/lambda/latest/dg/runtimes-update.html#runtime-management-controls)。
+ 将您的 Lambda 函数配置为访问 VPC 内的资源
+ [Lambda 函数死信队列](https://docs.amazonaws.cn/lambda/latest/dg/invocation-async.html#dlq)
+ [Lambda 环境变量](https://docs.amazonaws.cn/lambda/latest/dg/configuration-envvars.html)（自动支持的预留环境变量除外）
+ Lambda 函数与[管理具有层级的 Amazon Lambda 依赖关系](https://docs.amazonaws.cn/lambda/latest/dg/chapter-layers.html)
+ [使用 Amazon X-Ray](https://docs.amazonaws.cn/lambda/latest/dg/lambda-x-ray.html)
+ Lambda 预配置并发
**注意**  
Lambda@Edge 函数与所有 Lambda 函数共享相同的[区域并发](https://docs.amazonaws.cn/lambda/latest/dg/configuration-concurrency.html)功能。有关更多信息，请参阅 [有关 Lambda@Edge 的配额](cloudfront-limits.md#limits-lambda-at-edge)。
+ [使用容器映像创建 Lambda 函数](https://docs.amazonaws.cn/lambda/latest/dg/images-create.html)
+ [使用 arm64 架构的 Lambda 函数](https://docs.amazonaws.cn/lambda/latest/dg/foundation-arch.html)
+ 短暂存储超过 512 MB 的 Lambda 函数。
+ 使用[客户自主管理型密钥来加密 .zip 部署包](https://docs.amazonaws.cn/lambda/latest/dg/encrypt-zip-package.html)

## 支持的运行时
<a name="lambda-at-edge-restrictions-runtime"></a>

Lambda@Edge 支持最新版本的 Node.js 和 Python 运行时。有关支持的版本及其未来弃用日期的列表，请参阅《Amazon Lambda 开发人员指南》**中的[支持的运行时](https://docs.amazonaws.cn/lambda/latest/dg/lambda-runtimes.html#runtimes-supported)。

**提示**  
作为最佳实践，请使用所提供的运行时的最新版本来改进性能和新增功能。
您无法使用已弃用的 Node.js 版本创建或更新函数。您只能将现有函数与这些版本及 CloudFront 分配相关联。使用与分配关联的这些版本的函数将继续运行。但是，建议将您的函数转移到更新版本的 Node.js。有关更多信息，请参阅《Amazon Lambda 开发人员指南》**中的[运行时弃用策略](https://docs.amazonaws.cn/lambda/latest/dg/runtime-support-policy.html)和 GitHub 上的 [Node.js 发布计划](https://github.com/nodejs/Release#release-schedule)。

## CloudFront 标头
<a name="lambda-at-edge-restrictions-cloudfront-headers"></a>

Lambda@Edge 函数可以读取、编辑、删除或添加 [添加 CloudFront 请求标头](adding-cloudfront-headers.md) 中列出的任何 CloudFront 标头。

**备注**  
如果您希望 CloudFront 添加这些标头，则必须将 CloudFront 配置为使用[缓存策略](controlling-the-cache-key.md)或[源请求策略](controlling-origin-requests.md)来添加它们。
CloudFront 在查看器请求事件*之后* 添加标题，这意味着这些标头在查看器请求函数中不可用于 Lambda@Edge 函数。这些标头仅适用于源请求和源响应中的 Lambda@Edge 函数。
如果查看器请求包含具有这些名称的标头，并且您将 CloudFront 配置为使用[缓存策略](controlling-the-cache-key.md)或者[源请求策略](controlling-origin-requests.md)添加这些标头，则 CloudFront 会覆盖查看器请求中的标头值。面向查看器的函数可以看到查看器请求中的标头值，而面向源的函数则看到 CloudFront 添加的标头值。
如果查看器请求函数添加 `CloudFront-Viewer-Country` 标头，它将无法通过验证，并且 CloudFront 会将 HTTP 状态代码 502（无效网关）返回到查看器。

## 具有 Include Body（包含正文）选项的请求正文的限制
<a name="lambda-at-edge-restrictions-request-body"></a>

在选择**包含正文**选项以向您的 Lambda@Edge 函数公开请求正文时，以下信息和大小限制适用于公开或替换的正文部分。
+ CloudFront 总是对请求正文进行 base64 编码，然后再将其公开给 Lambda@Edge。
+ 如果请求正文很大，则 CloudFront 在将正文公开给 Lambda@Edge 之前将其截断，如下所示：
  + 对于查看器请求事件，正文将截断为 40 KB。
  + 对于源请求事件，正文将截断为 1 MB。
+ 如果以只读方式访问请求正文，则 CloudFront 将完整的原始请求正文发送到源。
+ 如果您的 Lambda@Edge 函数替换请求正文，则以下大小限制适用于该函数返回的正文：
  + 如果 Lambda@Edge 函数以纯文本形式返回正文：
    + 对于查看器请求事件，正文限制为 40KB。
    + 对于源请求事件，正文限制为 1MB。
  + 如果 Lambda@Edge 函数以 base64 编码文本形式返回正文：
    + 对于查看器请求事件，正文限制为 53.2KB。
    + 对于源请求事件，正文限制为 1.33MB。

**注意**  
如果 Lambda @Edge 函数返回的正文超出了这些限制，请求将失败，系统将显示 HTTP 502 状态代码 ([Lambda 验证错误](http-502-bad-gateway.md#http-502-lambda-validation-error))。建议您更新 Lambda @Edge 函数，使正文不超出这些限制。

## 响应超时和保持连接超时（仅自定义源）
<a name="timeout-for-lambda-edge-functions"></a>

如果您使用 Lambda@Edge 函数为分配源设置响应超时或保持连接超时，请确认您指定了您的源可以支持的值。有关更多信息，请参阅 [响应和保持连接超时限额](DownloadDistValuesOrigin.md#response-keep-alive-timeout-quota)。