

# 関数コードを記述する
<a name="writing-function-code"></a>

CloudFront Functions を使用すると、大規模でレイテンシーの影響を受けやすい CDN カスタマイズのための軽量な関数を JavaScript で記述できます。関数コードを使用して、CloudFront を通過するリクエストとレスポンスの操作、基本認証と認可の実行、エッジでの HTTP レスポンスの生成などを行うことができます。

CloudFront Functions の関数コードを記述する場合は、以下のトピックも参考になります。コード例については、「[CloudFront の CloudFront Functions の例](service_code_examples_cloudfront_functions_examples.md)」と GitHub の「[amazon-cloudfront-functions repository](https://github.com/aws-samples/amazon-cloudfront-functions)」を参照してください。

**Topics**
+ [関数の目的を決定する](function-code-choose-purpose.md)
+ [イベントの構造](functions-event-structure.md)
+ [JavaScript ランタイムの機能](functions-javascript-runtime-features.md)
+ [キーバリューストアのヘルパーメソッド](functions-custom-methods.md)
+ [オリジン変更のヘルパーメソッド](helper-functions-origin-modification.md)
+ [CloudFront SaaS Manager プロパティのヘルパーメソッド](saas-specific-logic-function-code.md)
+ [async および await を使用します。](async-await-syntax.md)
+ [CloudFront Functions の CWT サポート](cwt-support-cloudfront-functions.md)
+ [一般的なヘルパーメソッド](general-helper-methods.md)

# 関数の目的を決定する
<a name="function-code-choose-purpose"></a>

関数コードを記述する前に、関数の目的を決めます。CloudFront Functions の関数の大半は、次のいずれかを目的としています。

**Topics**
+ [ビューワーリクエストイベントタイプの HTTP リクエストの変更](#function-code-modify-request)
+ [ビューワーリクエストイベントタイプで HTTP レスポンスを生成する](#function-code-generate-response)
+ [ビューワーレスポンスイベントタイプの HTTP レスポンスの変更](#function-code-modify-response)
+ [接続リクエストイベントタイプの mTLS 接続を検証する](#function-code-connection-request)
+ [関連情報](#related-information-cloudfront-functions-purpose)

関数の目的にかかわらず、`handler` はあらゆる関数のエントリポイントです。CloudFront から関数に送られる `event` という単一の引数を使います。`event` は、HTTP リクエスト表記の JSON オブジェクトです (関数が HTTP レスポンスを変更する場合は、レスポンス)。

## ビューワーリクエストイベントタイプの HTTP リクエストの変更
<a name="function-code-modify-request"></a>

関数は、CloudFront がビューワー (クライアント) から受信する HTTP リクエストを変更し、変更されたリクエストを CloudFront に返して処理を続行できます。たとえば、関数コードで[キャッシュキー](understanding-the-cache-key.md)を正規化したり、リクエストヘッダーを変更したりできます。

HTTP リクエストを変更する関数を作成して発行する場合は、必ず*ビューワーリクエスト*イベントタイプの関連付けを追加してください。詳細については、「[関数を作成する](functions-tutorial.md#functions-tutorial-create)」を参照してください。これにより、CloudFront がビューワーからリクエストを受信するたびに、リクエストされたオブジェクトが CloudFront キャッシュにあるかどうかをチェックする前に、関数が実行されます。

**Example 例**  
次の擬似コードは、HTTP リクエストを変更する関数の構造を示しています。  

```
function handler(event) {
    var request = event.request;

    // Modify the request object here.

    return request;
}
```
この関数は、変更された `request` オブジェクトを CloudFront に返します。CloudFront は、CloudFront キャッシュでキャッシュヒットがないかチェックし、必要に応じてリクエストをオリジンに送信することで、返されたリクエストの処理を続行します。

## ビューワーリクエストイベントタイプで HTTP レスポンスを生成する
<a name="function-code-generate-response"></a>

関数は、エッジで HTTP レスポンスを生成し、キャッシュされたレスポンスまたは CloudFront によるそれ以降の処理をチェックすることなく、ビューワー (クライアント) に直接返すことができます。たとえば、関数コードは、リクエストを新しい URL にリダイレクトしたり、承認をチェックして、`401` や `403` レスポンスを非承認リクエストに返す場合があります。

HTTP レスポンスを生成する関数を作成する場合は、必ず*ビューワーリクエスト*イベントタイプを選択してください 。つまりこの関数は、CloudFront がビューワーからリクエストを受信するたびに、CloudFront がリクエストの処理を行う前に実行されます。

**Example 例**  
次の擬似コードは、HTTP 応答を生成する関数の構造を示しています。  

```
function handler(event) {
    var request = event.request;

    var response = ...; // Create the response object here,
                        // using the request properties if needed.

    return response;
}
```
この関数は、CloudFront に `response` オブジェクトを返します。CloudFront はこのオブジェクトを、CloudFront キャッシュをチェックしたり、オリジンにリクエストを送信したりすることなく、すぐにビューワーに戻します。

## ビューワーレスポンスイベントタイプの HTTP レスポンスの変更
<a name="function-code-modify-response"></a>

関数は、レスポンスが CloudFront キャッシュとオリジンのどちらから来たかに関係なく、CloudFront がビューワー (クライアント) に送信する前に HTTP レスポンスを変更できます。例えば、関数コードでレスポンスヘッダー、ステータスコード、本文のコンテンツを追加または変更する場合があります。

HTTP レスポンスを変更する関数を作成する場合は、必ず*ビューワーレスポンス*イベントタイプを選択してください。つまり関数は、レスポンスが CloudFront キャッシュまたはオリジンのどちらから来たかに関係なく、CloudFront がビューワーにレスポンスを返す前に実行されます。

**Example 例**  
次の擬似コードは、HTTP レスポンスを変更する関数の構造を示しています。  

```
function handler(event) {
    var request = event.request;
    var response = event.response;

    // Modify the response object here,
    // using the request properties if needed.

    return response;
}
```
この関数は変更された `response` オブジェクトを CloudFront に返し、CloudFront はこれをすぐにビューワーに返します。

## 接続リクエストイベントタイプの mTLS 接続を検証する
<a name="function-code-connection-request"></a>

接続関数は、カスタム検証および認証ロジックを提供するために TLS 接続中に実行される CloudFront Functions の一種です。接続関数は現在、相互 TLS (mTLS) 接続で使用できます。ここでは、クライアント証明書を検証し、標準証明書の検証を超えてカスタム認証ロジックを実装できます。接続関数は TLS ハンドシェイクプロセス中に実行され、証明書プロパティ、クライアント IP アドレス、または他の条件に基づいて接続を許可または拒否できます。

接続関数を作成して公開した後、mTLS が有効なディストリビューションとの*接続リクエスト*イベントタイプの関連付けを追加してください。これにより、クライアントが CloudFront との mTLS 接続を確立しようとするたびに関数が実行されるようになります。

**Example**  
次の擬似コードは、接続関数の構造を示しています。  

```
function connectionHandler(connection) {
    // Validate certificate and connection properties here.
    
    if (/* validation passes */) {
        connection.allow();
    } else {
        connection.deny();
    }
}
```
関数はヘルパーメソッドを使用して、接続を許可または拒否するかどうかを決定します。ビューワーリクエストおよびビューワーレスポンス関数とは異なり、接続関数は HTTP リクエストまたはレスポンスを変更できません。

## 関連情報
<a name="related-information-cloudfront-functions-purpose"></a>

CloudFront Functions の操作の詳細については、以下のトピックを参照してください。
+ [イベントの構造](functions-event-structure.md)
+ [JavaScript ランタイムの機能](functions-javascript-runtime-features.md)
+ [CloudFront Functions の例 ](service_code_examples_cloudfront_functions_examples.md)
+ [エッジ関数に対する制限](edge-functions-restrictions.md)

# CloudFront Functions のイベント構造
<a name="functions-event-structure"></a>

CloudFront Functions は、関数を実行するときに `event` オブジェクトを関数コードに入力として渡します。[関数をテスト](test-function.md)するときは、`event` オブジェクトを作成し、関数に渡します。関数をテストするために `event` オブジェクトを作成する場合は、`distributionDomainName` オブジェクト内の `distributionId`、`requestId`、`context` フィールドを省略できます。ヘッダーの名前が小文字であることを確認してください (CloudFront Functions が本番環境で関数に渡す `event` オブジェクトはすべて該当します)。

次に、このイベントオブジェクトの構造の概要を示します。

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

詳細については、以下の各トピックを参照してください。

**Topics**
+ [バージョンフィールド](#functions-event-structure-version)
+ [コンテキストオブジェクト](#functions-event-structure-context)
+ [接続イベントの構造](#functions-event-structure-connection)
+ [ビューワーオブジェクト](#functions-event-structure-viewer)
+ [リクエストオブジェクト](#functions-event-structure-request)
+ [レスポンスオブジェクト](#functions-event-structure-response)
+ [ステータスコードと本文](#functions-event-structure-status-body)
+ [クエリ文字列、ヘッダー、または Cookie の構造](#functions-event-structure-query-header-cookie)
+ [レスポンスオブジェクトの例](#functions-response-structure-example)
+ [イベントオブジェクトの例](#functions-event-structure-example)

## バージョンフィールド
<a name="functions-event-structure-version"></a>

`version` フィールドには、CloudFront Functions イベントオブジェクトのバージョンを指定する文字列が含まれます。現在のバージョンは `1.0` です。

## コンテキストオブジェクト
<a name="functions-event-structure-context"></a>

`context` オブジェクトには、イベントに関するコンテキスト情報が含まれます。次のフィールドが含まれています。

**`distributionDomainName`**  
イベントに関連付けられた標準ディストリビューションの CloudFront ドメイン名 (例: d111111abcdef8.cloudfront.net)。  
`distributionDomainName` フィールドは、関数が標準ディストリビューションに対して呼び出された場合にのみ表示されます。

**`endpoint`**  
イベントに関連付けられた接続グループの CloudFront ドメイン名 (例: d111111abcdef8.cloudfront.net)。  
`endpoint` フィールドは、関数がマルチテナントディストリビューションに対して呼び出された場合にのみ表示されます。

**`distributionId`**  
イベントに関連付けられたディストリビューションの ID (例: EDFDVBD6EXAMPLE) 。

**`eventType`**  
イベントタイプ (`viewer-request` または`viewer-response`)。

**`requestId`**  
CloudFront リクエスト (およびそれに関連付けられたレスポンス) を一意に識別する文字列。

## 接続イベントの構造
<a name="functions-event-structure-connection"></a>

接続関数は、ビューワー関数とは異なるイベント構造を受け取ります。接続イベントの構造とレスポンス形式の詳細については、「[CloudFront Connection Function を関連付ける](connection-functions.md)」を参照してください。

## ビューワーオブジェクト
<a name="functions-event-structure-viewer"></a>

`viewer` オブジェクトには、リクエストを送信したビューワー (クライアント) の IP アドレスを値とする `ip` フィールドが含まれています。ビューワーリクエストが HTTP プロキシまたはロードバランサーを通して来た場合、値はプロキシまたはロードバランサーの IP アドレスです。

## リクエストオブジェクト
<a name="functions-event-structure-request"></a>

`request` オブジェクトには、ビューワーから CloudFront への HTTP リクエスト表記が含まれています。関数に渡される `event` オブジェクトで、`request` オブジェクトは CloudFront がビューワーから受信した実際のリクエストを表しています。

関数コードが CloudFront に `request` オブジェクトを返す場合は、これと同じ構造を使用する必要があります。

`request` オブジェクトには、以下のフィールドが含まれています。

**`method`**  
リクエストの HTTP メソッド。関数コードが `request` を返す場合、このフィールドは変更できません。これは、`request` オブジェクト内唯一の読み取り専用フィールドです。

**`uri`**  
リクエストされたオブジェクトの相対パス。  
関数が `uri` 値を変更する場合、以下が適用されます。  
+ 新しい `uri` 値は、フォワードスラッシュ (`/`) で始まる必要があります。
+ 関数で `uri` 値を変更すると、ビューワーがリクエストしているオブジェクトが変更されます。
+ 関数で `uri` 値を変更しても、リクエストのキャッシュ動作やオリジンリクエストの送信先は変わりません。

**`querystring`**  
リクエストのクエリ文字列を表すオブジェクト。リクエストにクエリ文字列が含まれていない場合でも、`request` オブジェクトには空の `querystring` オブジェクトが含まれています。  
`querystring` オブジェクトには、リクエストのクエリ文字列パラメータ 1 つにつき 1 つのフィールドが含まれます。

**`headers`**  
リクエストの HTTP ヘッダーを表すオブジェクト。リクエストに `Cookie` ヘッダーが含まれている場合、それらのヘッダーは `headers` オブジェクトの一部ではありません。Cookieは `cookies` オブジェクトで個別に表示されます。  
`headers` オブジェクトには、リクエストのヘッダー 1 つにつき 1 つのフィールドが含まれます。ヘッダー名は、イベントオブジェクトでは ASCII 小文字に変換されます。また、関数コードで追加する場合、ヘッダー名を ASCII 小文字にする必要があります。CloudFront Functions がイベントオブジェクトを HTTP リクエストに変換し直すと、ヘッダー名の各単語の最初の文字が ASCII 文字の場合は大文字になります。CloudFront Functions は、ヘッダー名の非 ASCII 記号には変更を適用しません。例えば、関数内では `TÈst-header` は `tÈst-header` になります。非 ASCII 記号 `È` は変更されません。  
各単語はハイフン (`-`) で区切られます。例えば、関数コードが `example-header-name` という名前のヘッダーを追加した場合、CloudFront がこれを HTTP リクエストで `Example-Header-Name` に変換します。

**`cookies`**  
リクエスト (`Cookie` ヘッダー) の Cookie を表すオブジェクト。  
`cookies` オブジェクトには、リクエストの Cookie 1 つにつき 1 つのフィールドが含まれます。

クエリ文字列、ヘッダーおよび Cookie の構造の詳細については、「[クエリ文字列、ヘッダー、または Cookie の構造](#functions-event-structure-query-header-cookie)」を参照してください。

`event` オブジェクトの例については、「[イベントオブジェクトの例](#functions-event-structure-example)」を参照してください。

## レスポンスオブジェクト
<a name="functions-event-structure-response"></a>

`response` オブジェクトには、CloudFront Front からビューワーへの HTTP レスポンス表記が含まれています。関数に渡される `event` オブジェクトでは、`response` オブジェクトはビューワーリクエストに対する CloudFront の実際の応答を表します。

関数コードが `response` オブジェクトを返す場合は、これと同じ構造を使用する必要があります。

`response` オブジェクトには、以下のフィールドが含まれています。

**`statusCode`**  
レスポンスの HTTP ステータスコード。この値は文字列ではなく整数です。  
関数は `statusCode` を生成または変更できます。

**`statusDescription`**  
レスポンスの HTTP ステータスの説明。関数コードがレスポンスを生成する場合、このフィールドはオプションです。

**`headers`**  
レスポンスの HTTP ヘッダーを表すオブジェクト。レスポンスに `Set-Cookie` ヘッダーが含まれている場合、それらのヘッダーは `headers` オブジェクトの一部ではありません。Cookieは `cookies` オブジェクトで個別に表示されます。  
`headers` オブジェクトには、レスポンス内のヘッダー 1 つにつき 1 つのフィールドが含まれます。ヘッダー名は、イベントオブジェクトでは小文字に変換されます。また、関数コードで追加する場合、ヘッダー名を小文字にする必要があります。CloudFront Functions がイベントオブジェクトを HTTP レスポンスに変換し直すと、ヘッダー名の各単語の最初の文字が大文字になります。各単語はハイフン (`-`) で区切られます。例えば、関数コードが `example-header-name` という名前のヘッダーを追加した場合、CloudFront がこれを HTTP レスポンスの `Example-Header-Name` に変換します。

**`cookies`**  
レスポンス (`Set-Cookie` ヘッダー) で Cookie を表すオブジェクト。  
`cookies` オブジェクトには、レスポンスの Cookie 1 つにつき 1 つのフィールドが含まれます。

**`body`**  
`body` フィールドの追加はオプションで、関数で指定しない限り `response` オブジェクトには表示されません。関数は、CloudFront キャッシュまたはオリジンによって返された元の本文にアクセスできません。ビューワーレスポンス関数で `body` フィールドを指定しない場合、CloudFront キャッシュまたはオリジンから返された元の本文がビューワーに返されます。  
CloudFront がビューワーにカスタム本文を返すようにするには、`data` フィールドに本文コンテンツを指定し、`encoding` フィールドの本文エンコーディングを指定します。エンコーディングは、プレーンテキスト (`"encoding": "text"`) または Base64 でエンコードされたコンテンツ (`"encoding": "base64"`) として指定できます。  
ショートカットとして、本文の内容を `body` フィールド (`"body": "<specify the body content here>"`) で直接指定することもできます。これを行うときは、`data` および `encoding` フィールドを省略してください。この場合、CloudFront は、本文をプレーンテキストとして扱います。    
`encoding`  
`body` コンテンツ (`data` フィールド) のエンコーディング。有効なエンコードは `text` と `base64` のみです。  
`encoding` を `base64` と指定したが本文が有効な base64 でない場合、CloudFront はエラーを返します。  
`data`  
`body` コンテンツ。

変更されたステータスコードと本文の内容の詳細については、[ステータスコードと本文](#functions-event-structure-status-body) を参照してください。

ヘッダーと Cookie の構造の詳細については、「[クエリ文字列、ヘッダー、または Cookie の構造](#functions-event-structure-query-header-cookie)」を参照してください。

`response` オブジェクトの例については、「[レスポンスオブジェクトの例](#functions-response-structure-example)」を参照してください。

## ステータスコードと本文
<a name="functions-event-structure-status-body"></a>

CloudFront Functions を使用して、ビューワーのレスポンスステータスコードを更新したり、レスポンス本文すべてを新しく置き換えたり、レスポンス本文を削除したりできます。CloudFront キャッシュまたはオリジンからのレスポンスを評価した後でビューワーのレスポンスを更新する一般的なシナリオには、次のようなものがあります。
+ ステータスを変更して HTTP 200 ステータスコードを設定し、ビューワーに返す静的な本文コンテンツを作成する。
+ HTTP 301 または 302 ステータスコードを設定して、ユーザーを別のウェブサイトにリダイレクトする。
+ ビューワーレスポンスの本文を配信するか削除するかを決定します。

**注記**  
オリジンが 400 以上の HTTP エラーを返した場合、CloudFront Functions は実行されません。詳細については、「[すべてのエッジ機能に対する制限](edge-function-restrictions-all.md)」を参照してください。

HTTP レスポンスを使用する場合、CloudFront Functions は、レスポンス本文にアクセスできません。必要な値に設定することで本文コンテンツを置き換えたり、値を空に設定することで本文を削除したりできます。関数内の本文フィールドを更新しない場合は、CloudFront キャッシュまたはオリジンによって返された元の本文がビューワーに返されます。

**ヒント**  
CloudFront Functions を使用して本文を置き換える場合は、`content-encoding`、`content-type`、`content-length` などの対応するヘッダーを新しい本文のコンテンツに合わせてください。  
たとえば、CloudFront オリジンまたはキャッシュが `content-encoding: gzip` を返したが、ビューワーレスポンス関数が本文をプレーンテキストに設定した場合、関数は `content-encoding` と `content-type` ヘッダーもそれに応じて変更する必要があります。

CloudFront Functions が 400 以上の HTTP エラーを返すように設定されている場合、ビューワーには同じステータスコードに対して指定した[カスタムエラーページ](creating-custom-error-pages.md)は表示されません。

## クエリ文字列、ヘッダー、または Cookie の構造
<a name="functions-event-structure-query-header-cookie"></a>

クエリ文字列、ヘッダー、Cookie は同じ構造を共有します。クエリ文字列は、リクエストに表示される場合があります。ヘッダーは、リクエストとレスポンスに表示されます。Cookie は、リクエストとレスポンスに表示されます。

クエリ文字列、ヘッダーおよび Cookie はすべて、親 `querystring`、`headers`、`cookies`オブジェクトで一意のフィールドです。フィールド名は、クエリ文字列、ヘッダー、または Cookie の名前です。各フィールドには、クエリ文字列、ヘッダー、Cookie の値を持つ `value` プロパティが含まれます。

**Contents**
+ [クエリ文字列値またはクエリ文字列オブジェクト](#functions-event-structure-query)
+ [ヘッダーに関する特別な考慮事項](#functions-event-structure-headers)
+ [重複するクエリ文字列、ヘッダー、Cookie (`multiValue` 配列)](#functions-event-structure-multivalue)
+ [Cookie 属性](#functions-event-structure-cookie-attributes)

### クエリ文字列値またはクエリ文字列オブジェクト
<a name="functions-event-structure-query"></a>

関数は、クエリ文字列オブジェクトに加えてクエリ文字列値を返すことができます。クエリ文字列値を使用して、クエリ文字列パラメータを任意のカスタム順序で配置できます。

**Example 例**  
関数コードでクエリ文字列を変更するには、次のようなコードを使用します。  

```
var request = event.request; 
request.querystring = 'ID=42&Exp=1619740800&TTL=1440&NoValue=&querymv=val1&querymv=val2,val3';
```

### ヘッダーに関する特別な考慮事項
<a name="functions-event-structure-headers"></a>

ヘッダーのみの場合、ヘッダー名がイベントオブジェクトで小文字に変換されます。また、関数コードで追加する場合は、ヘッダー名を小文字にする必要があります。CloudFront Functions がイベントオブジェクトを HTTP リクエストまたはレスポンスに変換し直すと、ヘッダー名の各単語の最初の文字が大文字になります。各単語はハイフン (`-`) で区切られます。例えば、関数コードが `example-header-name` という名前のヘッダーを追加した場合、CloudFront がこれを HTTP リクエストまたはレスポンスの `Example-Header-Name` に変換します。

**Example 例**  
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'};
```

### 重複するクエリ文字列、ヘッダー、Cookie (`multiValue` 配列)
<a name="functions-event-structure-multivalue"></a>

HTTP リクエストまたはレスポンスには、同じ名前のクエリ文字列、ヘッダー、Cookie が含まれることがあります。この場合、重複するクエリ文字列、ヘッダー、Cookie は `request` または `response` オブジェクトの 1 つのフィールドに折りたたまれていますが、このフィールドには `multiValue` という名前の追加のプロパティが含まれます。`multiValue` プロパティには、重複するクエリ文字列、ヘッダー、Cookie の各値を含む配列が含まれます。

**Example 例**  
以下の `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`) は、`value` プロパティと `multiValue` プロパティの両方で繰り返されています。これにより、`multiValue` 配列をループして*すべての*値にアクセスできます。

関数コードで変更するクエリ文字列、ヘッダー、または Cookie に `multiValue` 配列が含まれている場合、CloudFront Functions は以下のルールを使用して変更を適用します。

1. `multiValue` 配列が存在し、変更がある場合は、その変更が適用されます。`value` プロパティの最初の要素は無視されます。

1. それ以外の場合は、`value` プロパティへの変更が適用され、それ以降の値 (存在する場合) は変更されません。

この `multiValue` プロパティは、前の例に示すように、HTTP リクエストまたはレスポンスに同じ名前の重複するクエリ文字列、ヘッダー、Cookie のいずれかが含まれている場合にのみ使用されます。ただし、1 つのクエリ文字列、ヘッダー、または Cookie に複数の値がある場合、`multiValue` プロパティは使用されません。

**Example 例**  
3 つの値を含む 1 つの `Accept` ヘッダーを持つリクエストについて考えてみます。  

```
Accept: application/json, application/xml, text/html
```
このヘッダーは、`request` オブジェクトで次のように表されます。  

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

### Cookie 属性
<a name="functions-event-structure-cookie-attributes"></a>

HTTP レスポンスの `Set-Cookie` ヘッダーでは、ヘッダーに Cookie の名前と値のペア、および必要に応じてセミコロンで区切られた属性のセットが含まれます。

**Example 例**  

```
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"
}
```

## レスポンスオブジェクトの例
<a name="functions-response-structure-example"></a>

次の例は、本文がビューワーレスポンス関数に置き換えられた `response` オブジェクト (ビューワーレスポンス関数の出力) を示しています。

```
{
  "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": "text/html"
      },
      "content-length": {
        "value": "86"
      }
    },
    "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"
          }
        ]
      }
    },
    
    // Adding the body field is optional and it will not be present in the response object
    // unless you specify it in your function.
    // Your function does not have access to the original body returned by the CloudFront
    // cache or origin.
    // If you don't specify the body field in your viewer response function, the original
    // body returned by the CloudFront cache or origin is returned to viewer.

     "body": {
      "encoding": "text",
      "data": "<!DOCTYPE html><html><body><p>Here is your custom content.</p></body></html>"
    }
  }
}
```

## イベントオブジェクトの例
<a name="functions-event-structure-example"></a>

以下は、完全な `event` オブジェクトの例です。これは、マルチテナントディストリビューションではなく、標準ディストリビューションの呼び出しの例です。マルチテナントディストリビューションの場合、`endpoint` フィールドは `distributionDomainName` の代わりに使用されます。`endpoint` の値は、イベントに関連付けられている接続グループの CloudFront ドメイン名 (d111111abcdef8.cloudfront.net など) です。

**注記**  
`event` オブジェクトは関数への入力です。関数は、`request` オブジェクト全体ではなく、`response` または `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"
                    }
                ]
            }
        }
    }
}
```

# CloudFront Functions の JavaScript ランタイムの機能
<a name="functions-javascript-runtime-features"></a>

CloudFront Functions の JavaScript ランタイム環境は [ ECMAScript (ES) バージョン 5.1](https://www.ecma-international.org/ecma-262/5.1/) に準拠しており、ES バージョン 6～12 の一部の機能をサポートしています。

最新の機能を利用するには、JavaScript ランタイム 2.0 を使用することをお勧めします。

JavaScript ランタイム 2.0 の機能には、1.0 と比較して以下の変更があります。
+ バッファモジュールメソッドが利用可能です。
+ 以下の非標準の文字列プロトタイプメソッドは使用できません。
  + `String.prototype.bytesFrom()`
  + `String.prototype.fromBytes()`
  + `String.prototype.fromUTF8()`
  + `String.prototype.toBytes()`
  + `String.prototype.toUTF8()`
+ 暗号モジュールには次の変更があります。
  + `hash.digest()` - エンコーディングを指定しない場合、戻り型は `Buffer` に変更されます。
  + `hmac.digest()` - エンコーディングを指定しない場合、戻り型は `Buffer` に変更されます。
+ その他の新しい機能の詳細については、「[CloudFront Functions の JavaScript ランタイム 2.0 の機能](functions-javascript-runtime-20.md)」を参照してください。

**Topics**
+ [JavaScript ランタイム 1.0 の機能](functions-javascript-runtime-10.md)
+ [JavaScript ランタイム 2.0 の機能](functions-javascript-runtime-20.md)

# CloudFront Functions の JavaScript ランタイム 1.0 の機能
<a name="functions-javascript-runtime-10"></a>

CloudFront Functions の JavaScript ランタイム環境は [ ECMAScript (ES) バージョン 5.1](https://262.ecma-international.org/5.1/) に準拠しており、ES バージョン 6～9 の一部の機能をサポートしています。また、ES 仕様に含まれない非標準メソッドも提供しています。

次のトピックでは、サポートされるすべての言語機能の一覧を示します。

**Topics**
+ [主要機能](#writing-functions-javascript-features-core)
+ [プリミティブオブジェクト](#writing-functions-javascript-features-primitive-objects)
+ [ビルトインオブジェクト](#writing-functions-javascript-features-builtin-objects)
+ [エラーのタイプ](#writing-functions-javascript-features-error-types)
+ [Globals](#writing-functions-javascript-features-globals)
+ [ビルトインモジュール](#writing-functions-javascript-features-builtin-modules)
+ [制限された機能](#writing-functions-javascript-features-restricted-features)

## 主要機能
<a name="writing-functions-javascript-features-core"></a>

ES の次の主要機能がサポートされています。

**Types]**  
すべての ES 5.1 タイプでサポートされています。これには、ブール値、数値、文字列、オブジェクト、配列、関数、関数コンストラクタ、正規表現が含まれます。

**演算子**  
すべての ES 5.1 演算子でサポートされています。  
ES 7 指数演算子 (`**`) がサポートされています。

**ステートメント**  
`const` および `let` ステートメントはサポートされていません。
次の ES 5.1 ステートメントがサポートされています。  
+ `break`
+ `catch`
+ `continue`
+ `do-while`
+ `else`
+ `finally`
+ `for`
+ `for-in`
+ `if`
+ `return`
+ `switch`
+ `throw`
+ `try`
+ `var`
+ `while`
+ ラベル付きステートメント

**リテラル**  
ES 6 テンプレートリテラル (複数行の文字列、式の補間、および入れ子テンプレート) がサポートされています。

**関数**  
すべての ES 5.1 機能がサポートされています。  
ES 6 のアロー関数、ES 6 のレストパラメータ (残余因数) 構文がサポートされています。

**Unicode**  
ソーステキストおよび文字列リテラルには、Unicode でエンコードされた文字を含めることができます。6 文字の Unicode エスケープシーケンス (コードポイント、例: `\uXXXX`) もサポートされています。

**Strict モード**  
関数は Strict モードで動作するため、関数コードに `use strict` ステートメントを追加する必要はありません。これは変更できません。

## プリミティブオブジェクト
<a name="writing-functions-javascript-features-primitive-objects"></a>

以下の ES プリミティブオブジェクトがサポートされています。

**オブジェクト**  
オブジェクトについて以下の ES 5.1 メソッドがサポートされています。  
+ `create` (プロパティリストなし)
+ `defineProperties`
+ `defineProperty`
+ `freeze`
+ `getOwnPropertyDescriptor`
+ `getOwnPropertyNames`
+ `getPrototypeOf`
+ `hasOwnProperty`
+ `isExtensible`
+ `isFrozen`
+ `prototype.isPrototypeOf`
+ `isSealed`
+ `keys`
+ `preventExtensions`
+ `prototype.propertyIsEnumerable`
+ `seal`
+ `prototype.toString`
+ `prototype.valueOf`
オブジェクトについて以下の ES 6 メソッドがサポートされています。  
+ `assign`
+ `is`
+ `prototype.setPrototypeOf`
オブジェクトについて以下の ES 8 メソッドがサポートされています。  
+ `entries`
+ `values`

**文字列**  
文字列について以下の ES 5.1 メソッドがサポートされています。  
+ `fromCharCode`
+ `prototype.charAt`
+ `prototype.concat`
+ `prototype.indexOf`
+ `prototype.lastIndexOf`
+ `prototype.match`
+ `prototype.replace`
+ `prototype.search`
+ `prototype.slice`
+ `prototype.split`
+ `prototype.substr`
+ `prototype.substring`
+ `prototype.toLowerCase`
+ `prototype.trim`
+ `prototype.toUpperCase`
文字列について以下の ES 6 メソッドがサポートされています。  
+ `fromCodePoint`
+ `prototype.codePointAt`
+ `prototype.endsWith`
+ `prototype.includes`
+ `prototype.repeat`
+ `prototype.startsWith`
文字列について以下の ES 8 メソッドがサポートされています。  
+ `prototype.padStart`
+ `prototype.padEnd`
文字列について以下の ES 9 メソッドがサポートされています。  
+ `prototype.trimStart`
+ `prototype.trimEnd`
文字列について以下の非標準メソッドがサポートされています。  
+ `prototype.bytesFrom(array | string, encoding)`

  オクテット列またはエンコードされた文字列からバイト文字列を作成します。文字列エンコーディングオプションは `hex`、`base64`、`base64url`です。
+ `prototype.fromBytes(start[, end])`

  バイト文字列から Unicode 文字列を作成します。各バイトは、対応する Unicode コードポイントで置き換えられます。
+ `prototype.fromUTF8(start[, end])`

  UTF-8 でエンコードされたバイト文字列から Unicode 文字列を作成します。エンコーディングが正しくない場合は、`null` が返されます。
+ `prototype.toBytes(start[, end])`

  Unicode 文字列からバイト文字列を作成します。すべての文字は [0,255] の範囲内にある必要があります。そうでない場合は、`null` が返されます。
+ `prototype.toUTF8(start[, end])`

  Unicode 文字列から UTF-8 でエンコードされたバイト文字列を作成します。

**数値**  
番号に関するすべての ES 5.1 メソッドがサポートされています。  
番号について以下の ES 6 メソッドがサポートされています。  
+ `isFinite`
+ `isInteger`
+ `isNaN`
+ `isSafeInteger`
+ `parseFloat`
+ `parseInt`
+ `prototype.toExponential`
+ `prototype.toFixed`
+ `prototype.toPrecision`
+ `EPSILON`
+ `MAX_SAFE_INTEGER`
+ `MAX_VALUE`
+ `MIN_SAFE_INTEGER`
+ `MIN_VALUE`
+ `NEGATIVE_INFINITY`
+ `NaN`
+ `POSITIVE_INFINITY`

## ビルトインオブジェクト
<a name="writing-functions-javascript-features-builtin-objects"></a>

ES の以下のビルトインオブジェクトがサポートされています。

**Math**  
ES 5.1 のすべての Math メソッドがサポートされています。  
CloudFront Functions runtime 環境では、`Math.random()` 実装に、関数が実行されたときのタイムスタンプがシードされた OpenBSD `arc4random` を使用します。
以下の ES 6 Math メソッドがサポートされています。  
+ `acosh`
+ `asinh`
+ `atanh`
+ `cbrt`
+ `clz32`
+ `cosh`
+ `expm1`
+ `fround`
+ `hypot`
+ `imul`
+ `log10`
+ `log1p`
+ `log2`
+ `sign`
+ `sinh`
+ `tanh`
+ `trunc`
+ `E`
+ `LN10`
+ `LN2`
+ `LOG10E`
+ `LOG2E`
+ `PI`
+ `SQRT1_2`
+ `SQRT2`

**日付**  
すべての ES 5.1 の `Date` 機能がサポートされています。  
セキュリティ上の理由から、`Date` は、単一の関数実行の有効期間中、常に同じ値 (関数の開始時間) を返します。詳細については、「[制限された機能](#writing-functions-javascript-features-restricted-features)」を参照してください。

**関数**  
`apply`、`bind`、`call` メソッドがサポートされています。  
関数コンストラクタはサポートされていません。

**正規表現**  
すべての ES 5.1 の正規表現機能がサポートされています。正規表現言語は Perl 互換です。ES 9 の名前付きキャプチャグループがサポートされています。

**JSON**  
`parse`、`stringify` を含むすべての ES 5.1 JSON 機能がサポートされています。

**配列**  
配列について以下の ES 5.1 メソッドがサポートされています。  
+ `isArray`
+ `prototype.concat`
+ `prototype.every`
+ `prototype.filter`
+ `prototype.forEach`
+ `prototype.indexOf`
+ `prototype.join`
+ `prototype.lastIndexOf`
+ `prototype.map`
+ `prototype.pop`
+ `prototype.push`
+ `prototype.reduce`
+ `prototype.reduceRight`
+ `prototype.reverse`
+ `prototype.shift`
+ `prototype.slice`
+ `prototype.some`
+ `prototype.sort`
+ `prototype.splice`
+ `prototype.unshift`
配列について以下の ES 6 メソッドがサポートされています。  
+ `of`
+ `prototype.copyWithin`
+ `prototype.fill`
+ `prototype.find`
+ `prototype.findIndex`
配列について以下の ES 7 メソッドがサポートされています。  
+ `prototype.includes`

**型付き配列**  
以下の ES 6 型付き配列がサポートされています。  
+ `Int8Array`
+ `Uint8Array`
+ `Uint8ClampedArray`
+ `Int16Array`
+ `Uint16Array`
+ `Int32Array`
+ `Uint32Array`
+ `Float32Array`
+ `Float64Array`
+ `prototype.copyWithin`
+ `prototype.fill`
+ `prototype.join`
+ `prototype.set`
+ `prototype.slice`
+ `prototype.subarray`
+ `prototype.toString`

**ArrayBuffer**  
`ArrayBuffer` について以下のメソッドがサポートされています。  
+ `prototype.isView`
+ `prototype.slice`

**promise**  
promise について以下のメソッドがサポートされています。  
+ `reject`
+ `resolve`
+ `prototype.catch`
+ `prototype.finally`
+ `prototype.then`

**Crypto**  
暗号モジュールは、標準のハッシュおよびハッシュベースのメッセージ認証コード (HMAC) ヘルパーを提供します。`require('crypto')` を使用してモジュールをロードできます。モジュールは、Node.js の相対物とまったく同じように動作する以下のメソッドを公開します。  
+ `createHash(algorithm)`
+ `hash.update(data)`
+ `hash.digest([encoding])`
+ `createHmac(algorithm, secret key)`
+ `hmac.update(data)`
+ `hmac.digest([encoding])`
詳細については、「ビルトインモジュールセクション」の「[Crypto (ハッシュと HMAC)](#writing-functions-javascript-features-builtin-modules-crypto)」を参照してください。

**コンソール**  
これはデバッグ用のヘルパーオブジェクトです。ログメッセージを記録するための `log()` メソッドのみサポートしています。  
CloudFront Functions は、`console.log('a', 'b')` などのカンマ構文をサポートしていません。代わりに、`console.log('a' + ' ' + 'b')` 形式を使用してください。

## エラーのタイプ
<a name="writing-functions-javascript-features-error-types"></a>

以下のエラーオブジェクトがサポートされています。
+ `Error`
+ `EvalError`
+ `InternalError`
+ `MemoryError`
+ `RangeError`
+ `ReferenceError`
+ `SyntaxError`
+ `TypeError`
+ `URIError`

## Globals
<a name="writing-functions-javascript-features-globals"></a>

`globalThis` オブジェクトはサポートされています。

以下の ES 5.1 グローバル関数がサポートされています。
+ `decodeURI`
+ `decodeURIComponent`
+ `encodeURI`
+ `encodeURIComponent`
+ `isFinite`
+ `isNaN`
+ `parseFloat`
+ `parseInt`

以下のグローバル定数がサポートされています。
+ `NaN`
+ `Infinity`
+ `undefined`

## ビルトインモジュール
<a name="writing-functions-javascript-features-builtin-modules"></a>

以下のビルトインモジュールがサポートされています。

**Topics**
+ [Crypto (ハッシュと HMAC)](#writing-functions-javascript-features-builtin-modules-crypto)
+ [クエリ文字列](#writing-functions-javascript-features-builtin-modules-query-string)

### Crypto (ハッシュと HMAC)
<a name="writing-functions-javascript-features-builtin-modules-crypto"></a>

暗号モジュール (`crypto`) は、標準のハッシュおよびハッシュベースのメッセージ認証コード (HMAC) ヘルパーを提供します。`require('crypto')` を使用してモジュールをロードできます。このモジュールは、Node.js の相対物とまったく同じように動作する以下のメソッドを提供します。

**ハッシュメソッド**

`crypto.createHash(algorithm)`  
ハッシュオブジェクトを作成して返します。このハッシュオブジェクトは、指定されたアルゴリズム (`md5`、`sha1`、`sha256` のいずれか) を使用してハッシュダイジェストの生成に使用できます。

`hash.update(data)`  
指定された `data` を使用してハッシュコンテンツを更新します。

`hash.digest([encoding])`  
`hash.update()` を使用して渡されたすべてのデータのダイジェストを計算します。エンコードは `hex`、`base64`、`base64url` のいずれかを使用します。

**HMAC メソッド**

`crypto.createHmac(algorithm, secret key)`  
指定された `algorithm` と `secret key` を使用する HMAC オブジェクトを作成して返します。アルゴリズムは `md5`、`sha1`、`sha256` のいずれかを使用します。

`hmac.update(data)`  
指定された `data` を使用して HMAC コンテンツを更新します 。

`hmac.digest([encoding])`  
`hmac.update()` を使用して渡されたすべてのデータのダイジェストを計算します。エンコードは `hex`、`base64`、`base64url` のいずれかを使用します。

### クエリ文字列
<a name="writing-functions-javascript-features-builtin-modules-query-string"></a>

**注記**  
[CloudFront Functions イベントオブジェクト](functions-event-structure.md)は、URL クエリ文字列を自動的に解析します。つまり、ほとんどの場合、このモジュールを使用する必要はありません。

クエリ文字列モジュール (`querystring`) は、URL クエリ文字列を解析および書式設定するためのメソッドを提供します。`require('querystring')` を使用してモジュールをロードできます。このモジュールは、以下のメソッドを提供します。

`querystring.escape(string)`  
URL は `string` をエンコードし、エスケープしたクエリ文字列を返します。このメソッドは `querystring.stringify()` で使用するため、直接使用しないでください。

`querystring.parse(string[, separator[, equal[, options]]])`  
クエリ文字列 (`string`) を解析し、オブジェクトを返します。  
`separator` パラメータは、クエリ文字列のキーと値のペアを区切る substring です。デフォルトでは、`&` です。  
`equal` パラメータは、クエリ文字列のキーと値を区切る substring です。デフォルトでは、`=` です。  
`options` パラメータは、以下のキーを持つオブジェクトです。    
`decodeURIComponent function`  
クエリ文字列のパーセントエンコーディングされた文字を decode する関数です。デフォルトでは、`querystring.unescape()` です。  
`maxKeys number`  
解析するキーの最大数。デフォルトでは、`1000` です。キーカウントの制限を解除するには、`0` の値を使用します。
デフォルトでは、クエリ文字列のパーセントエンコーディングされた文字は、UTF-8 エンコーディングを使用していると見なされます。無効な UTF-8 シーケンスは、`U+FFFD` 置換文字に置き換えられます。  
たとえば、次のクエリ文字列の場合:  

```
'name=value&abc=xyz&abc=123'
```
`querystring.parse()`の戻り値は次のとおりです。  

```
{
name: 'value',
abc: ['xyz', '123']
}
```
`querystring.decode()` は のエイリアスです。`querystring.parse()`

`querystring.stringify(object[, separator[, equal[, options]]])`  
`object` をシリアル化し、クエリ文字列を返します。  
`separator` パラメータは、クエリ文字列のキーと値のペアを区切る substring です。デフォルトでは、`&` です。  
`equal` パラメータは、クエリ文字列のキーと値を区切る substring です。デフォルトでは、`=` です。  
`options` パラメータは、以下のキーを持つオブジェクトです。    
`encodeURIComponent function`  
URL-unsafe 文字をクエリ文字列のパーセントエンコーディングに変換するために使用される関数です。デフォルトでは、`querystring.escape()` です。
デフォルトでは、クエリ文字列でパーセントエンコーディングが必要な文字は UTF-8 としてエンコードされます。別のエンコーディングを使用するには、`encodeURIComponent` オプションを指定します。  
以下のコードでの例:  

```
querystring.stringify({ name: 'value', abc: ['xyz', '123'], anotherName: '' });
```
戻り値:  

```
'name=value&abc=xyz&abc=123&anotherName='
```
`querystring.encode()` は のエイリアスです。`querystring.stringify()`

`querystring.unescape(string)`  
指定された `string` 内の URL パーセントエンコーディングされた文字をデコードし、エスケープしていないクエリ文字列を返します。このメソッドは `querystring.parse()`で使用するため、直接使用しないでください。

## 制限された機能
<a name="writing-functions-javascript-features-restricted-features"></a>

次の JavaScript 言語機能は、セキュリティ上の問題により、サポートされていないか、制限されています。

**動的コード評価**  
動的コード評価はサポートされていません。`eval()`、`Function` 両方のコンストラクタが試行された場合、エラーをスローします。たとえば、`const sum = new Function('a', 'b', 'return a + b')` はエラーをスローします。

**タイマー **  
`setTimeout()`、`setImmediate()`、`clearTimeout()` 関数はサポートされていません。関数実行中に defer または yield する規定はありません。関数は同期的に実行しないと完了できません。

**日付とタイムスタンプ**  
セキュリティ上の理由から、高解像度タイマーにはアクセスできません。現在の時刻を照会するすべての `Date` メソッドは、単一の関数実行の存続期間中は常に同じ値を返します。返されるタイムスタンプは、関数の実行を開始した時刻です。したがって、関数内で経過時間を測定することはできません。

**ファイルシステムへのアクセス**  
ファイルシステムにはアクセスできません。たとえば、Node.js にあるようなファイルシステムアクセス用の `fs` モジュールはありません。

**プロセスへのアクセス**  
プロセスにはアクセスできません。例えば、Node.js にあるような、情報アクセスを処理するための `process` グローバルオブジェクトはありません。

**環境変数**  
環境変数にはアクセスできません。  
この代わりに、CloudFront KeyValueStore を使用して、CloudFront Functions のための key-value ペアの一元化されたデータストアを作成できます。CloudFront KeyValueStore を使用すると、コード変更をデプロイする必要なく、設定データを動的に更新できます。CloudFront KeyValueStore を使用するには、[JavaScript ランタイム 2.0](functions-javascript-runtime-20.md) を使用する必要があります。詳細については、「[Amazon CloudFront KeyValueStore](kvs-with-functions.md)」を参照してください。

**ネットワークアクセス**  
ネットワークコールはサポートされていません。たとえば、XHR、HTTP (S)、ソケットはサポートされていません。

# CloudFront Functions の JavaScript ランタイム 2.0 の機能
<a name="functions-javascript-runtime-20"></a>

CloudFront Functions の JavaScript ランタイム環境は [ ECMAScript (ES) バージョン 5.1](https://262.ecma-international.org/5.1/) に準拠しており、ES バージョン 6～12 の一部の機能をサポートしています。また、ES 仕様に含まれない非標準メソッドも提供しています。次のトピックでは、このランタイムでサポートされるすべての機能を一覧表示します。

**Topics**
+ [主要機能](#writing-functions-javascript-features-core-20)
+ [プリミティブオブジェクト](#writing-functions-javascript-features-primitive-objects-20)
+ [ビルトインオブジェクト](#writing-functions-javascript-features-builtin-objects-20)
+ [エラーのタイプ](#writing-functions-javascript-features-error-types-20)
+ [Globals](#writing-functions-javascript-features-globals-20)
+ [ビルトインモジュール](#writing-functions-javascript-features-builtin-modules-20)
+ [制限された機能](#writing-functions-javascript-features-restricted-features-20)

## 主要機能
<a name="writing-functions-javascript-features-core-20"></a>

ES の次の主要機能がサポートされています。

**Types]**  
すべての ES 5.1 タイプでサポートされています。これには、ブール値、数値、文字列、オブジェクト、配列、関数、正規表現が含まれます。

**演算子**  
すべての ES 5.1 演算子でサポートされています。  
ES 7 指数演算子 (`**`) がサポートされています。

**ステートメント**  
次の ES 5.1 ステートメントがサポートされています。  
+ `break`
+ `catch`
+ `continue`
+ `do-while`
+ `else`
+ `finally`
+ `for`
+ `for-in`
+ `if`
+ `label`
+ `return`
+ `switch`
+ `throw`
+ `try`
+ `var`
+ `while`
次の ES 6 ステートメントがサポートされています。  
+ `const`
+ `let`
次の ES 8 ステートメントがサポートされています。  
+ `async`
+ `await`
`async`、`await`、`const`、`let` は JavaScript ランタイム 2.0 でサポートされています。  
`await` は `async` 関数内でのみ使用できます。`async` 引数とクロージャはサポートされていません。

**リテラル**  
ES 6 テンプレートリテラル (複数行の文字列、式の補間、および入れ子テンプレート) がサポートされています。

**関数**  
すべての ES 5.1 機能がサポートされています。  
ES 6 のアロー関数、ES 6 のレストパラメータ (残余因数) 構文がサポートされています。

**Unicode**  
ソーステキストおよび文字列リテラルには、Unicode でエンコードされた文字を含めることができます。6 文字の Unicode エスケープシーケンス (コードポイント、例: `\uXXXX`) もサポートされています。

**Strict モード**  
関数は Strict モードで動作するため、関数コードに `use strict` ステートメントを追加する必要はありません。これは変更できません。

## プリミティブオブジェクト
<a name="writing-functions-javascript-features-primitive-objects-20"></a>

以下の ES プリミティブオブジェクトがサポートされています。

**オブジェクト**  
オブジェクトについて以下の ES 5.1 メソッドがサポートされています。  
+ `Object.create()` (プロパティリストなし)
+ `Object.defineProperties()`
+ `Object.defineProperty()`
+ `Object.freeze()`
+ `Object.getOwnPropertyDescriptor()`
+ `Object.getOwnPropertyDescriptors()`
+ `Object.getOwnPropertyNames()`
+ `Object.getPrototypeOf()`
+ `Object.isExtensible()`
+ `Object.isFrozen()`
+ `Object.isSealed()`
+ `Object.keys()`
+ `Object.preventExtensions()`
+ `Object.seal()`
オブジェクトについて以下の ES 6 メソッドがサポートされています。  
+ `Object.assign()`
オブジェクトについて以下の ES 8 メソッドがサポートされています。  
+ `Object.entries()`
+ `Object.values()`
オブジェクトについて以下の ES 5.1 プロトタイプメソッドがサポートされています。  
+ `Object.prototype.hasOwnProperty()`
+ `Object.prototype.isPrototypeOf()`
+ `Object.prototype.propertyIsEnumerable()`
+ `Object.prototype.toString()`
+ `Object.prototype.valueOf()`
オブジェクトについて以下の ES 6 プロトタイプメソッドがサポートされています。  
+ `Object.prototype.is()`
+ `Object.prototype.setPrototypeOf()`

**String**  
文字列について以下の ES 5.1 メソッドがサポートされています。  
+ `String.fromCharCode()`
文字列について以下の ES 6 メソッドがサポートされています。  
+ `String.fromCodePoint()`
文字列について以下の ES 5.1 プロトタイプメソッドがサポートされています。  
+ `String.prototype.charAt()`
+ `String.prototype.concat()`
+ `String.prototype.indexOf()`
+ `String.prototype.lastIndexOf()`
+ `String.prototype.match()`
+ `String.prototype.replace()`
+ `String.prototype.search()`
+ `String.prototype.slice()`
+ `String.prototype.split()`
+ `String.prototype.substr()`
+ `String.prototype.substring()`
+ `String.prototype.toLowerCase()`
+ `String.prototype.trim()`
+ `String.prototype.toUpperCase()`
文字列について以下の ES 6 プロトタイプメソッドがサポートされています。  
+ `String.prototype.codePointAt()`
+ `String.prototype.endsWith()`
+ `String.prototype.includes()`
+ `String.prototype.repeat()`
+ `String.prototype.startsWith()`
文字列について以下の ES 8 プロトタイプメソッドがサポートされています。  
+ `String.prototype.padStart()`
+ `String.prototype.padEnd()`
文字列について以下の ES 9 プロトタイプメソッドがサポートされています。  
+ `String.prototype.trimStart()`
+ `String.prototype.trimEnd()`
文字列について以下の ES 12 プロトタイプメソッドがサポートされています。  
+ `String.prototype.replaceAll()`
**注記**  
`String.prototype.replaceAll()` は JavaScript ランタイム 2.0 で新しく追加されました。

**Number**  
すべての ES 5 番号がサポートされています。  
番号について以下の ES 6 プロパティがサポートされています。  
+ `Number.EPSILON`
+ `Number.MAX_SAFE_INTEGER`
+ `Number.MIN_SAFE_INTEGER`
+ `Number.MAX_VALUE`
+ `Number.MIN_VALUE`
+ `Number.NaN`
+ `Number.NEGATIVE_INFINITY`
+ `Number.POSITIVE_INFINITY`
番号について以下の ES 6 メソッドがサポートされています。  
+ `Number.isFinite()`
+ `Number.isInteger()`
+ `Number.isNaN()`
+ `Number.isSafeInteger()`
+ `Number.parseInt()`
+ `Number.parseFloat()`
番号について以下の ES 5.1 プロトタイプメソッドがサポートされています。  
+ `Number.prototype.toExponential()`
+ `Number.prototype.toFixed()`
+ `Number.prototype.toPrecision()`
ES 12 数字区切り文字がサポートされています。  
ES 12 数字区切り文字は JavaScript ランタイム 2.0 で新しく追加されました。

## ビルトインオブジェクト
<a name="writing-functions-javascript-features-builtin-objects-20"></a>

ES の以下のビルトインオブジェクトがサポートされています。

**Math**  
ES 5.1 のすべての Math メソッドがサポートされています。  
CloudFront Functions runtime 環境では、`Math.random()` 実装に、関数が実行されたときのタイムスタンプがシードされた OpenBSD `arc4random` を使用します。
以下の ES 6 数学的プロパティがサポートされています。  
+ `Math.E`
+ `Math.LN10`
+ `Math.LN2`
+ `Math.LOG10E`
+ `Math.LOG2E`
+ `Math.PI`
+ `Math.SQRT1_2`
+ `Math.SQRT2`
以下の ES 6 Math メソッドがサポートされています。  
+ `Math.abs()`
+ `Math.acos()`
+ `Math.acosh()`
+ `Math.asin()`
+ `Math.asinh()`
+ `Math.atan()`
+ `Math.atan2()`
+ `Math.atanh()`
+ `Math.cbrt()`
+ `Math.ceil()`
+ `Math.clz32()`
+ `Math.cos()`
+ `Math.cosh()`
+ `Math.exp()`
+ `Math.expm1()`
+ `Math.floor()`
+ `Math.fround()`
+ `Math.hypot()`
+ `Math.imul()`
+ `Math.log()`
+ `Math.log1p()`
+ `Math.log2()`
+ `Math.log10()`
+ `Math.max()`
+ `Math.min()`
+ `Math.pow()`
+ `Math.random()`
+ `Math.round()`
+ `Math.sign()`
+ `Math.sinh()`
+ `Math.sin()`
+ `Math.sqrt()`
+ `Math.tan()`
+ `Math.tanh()`
+ `Math.trunc()`

**日付**  
すべての ES 5.1 の `Date` 機能がサポートされています。  
セキュリティ上の理由から、`Date` は、単一の関数実行の有効期間中、常に同じ値 (関数の開始時間) を返します。詳細については、「[制限された機能](functions-javascript-runtime-10.md#writing-functions-javascript-features-restricted-features)」を参照してください。

**関数**  
以下の ES 5.1 プロトタイプメソッドがサポートされています。  
+ `Function.prototype.apply()`
+ `Function.prototype.bind()`
+ `Function.prototype.call()`
関数コンストラクタはサポートされていません。

**正規表現**  
すべての ES 5.1 の正規表現機能がサポートされています。正規表現言語は Perl 互換です。  
以下の ES 5.1 プロトタイプアクセサプロパティがサポートされています。  
+ `RegExp.prototype.global`
+ `RegExp.prototype.ignoreCase`
+ `RegExp.protoype.multiline`
+ `RegExp.protoype.source`
+ `RegExp.prototype.sticky`
+ `RegExp.prototype.flags`
**注記**  
`RegExp.prototype.sticky` および `RegExp.prototype.flags` は JavaScript ランタイム 2.0 で新しく追加されました。
以下の ES 5.1 プロトタイプメソッドがサポートされています。  
+ `RegExp.prototype.exec()`
+ `RegExp.prototype.test()`
+ `RegExp.prototype.toString()`
+ `RegExp.prototype[@@replace]()`
+ `RegExp.prototype[@@split]()`
**注記**  
`RegExp.prototype[@@split]()` は JavaScript ランタイム 2.0 で新しく追加されました。
以下の ES 5.1 インスタンスプロパティがサポートされています。  
+ `lastIndex`
ES 9 の名前付きキャプチャグループがサポートされています。

**JSON**  
以下の ES 5.1 メソッドがサポートされています。  
+ `JSON.parse()`
+ `JSON.stringify()`

**配列**  
配列について以下の ES 5.1 メソッドがサポートされています。  
+ `Array.isArray()`
配列について以下の ES 6 メソッドがサポートされています。  
+ `Array.of()`
以下の ES 5.1 プロトタイプメソッドがサポートされています。  
+ `Array.prototype.concat()`
+ `Array.prototype.every()`
+ `Array.prototype.filter()`
+ `Array.prototype.forEach()`
+ `Array.prototype.indexOf()`
+ `Array.prototype.join()`
+ `Array.prototype.lastIndexOf()`
+ `Array.prototype.map()`
+ `Array.prototype.pop()`
+ `Array.prototype.push()`
+ `Array.prototype.reduce()`
+ `Array.prototype.reduceRight()`
+ `Array.prototype.reverse()`
+ `Array.prototype.shift()`
+ `Array.prototype.slice()`
+ `Array.prototype.some()`
+ `Array.prototype.sort()`
+ `Array.prototype.splice()`
+ `Array.prototype.unshift()`
以下の ES 6 プロトタイプメソッドがサポートされています。  
+ `Array.prototype.copyWithin()`
+ `Array.prototype.fill()`
+ `Array.prototype.find()`
+ `Array.prototype.findIndex()`
以下の ES 7 プロトタイプメソッドがサポートされています。  
+ `Array.prototype.includes()`

**型付き配列**  
以下の ES 6 型付き配列コンストラクターがサポートされています。  
+ `Float32Array`
+ `Float64Array`
+ `Int8Array`
+ `Int16Array`
+ `Int32Array`
+ `Uint8Array`
+ `Uint8ClampedArray`
+ `Uint16Array`
+ `Uint32Array`
以下の ES 6 メソッドがサポートされています。  
+ `TypedArray.from()`
+ `TypedArray.of()`
**注記**  
`TypedArray.from()` および `TypedArray.of()` は JavaScript ランタイム 2.0 で新しく追加されました。
以下の ES 6 プロトタイプメソッドがサポートされています。  
+ `TypedArray.prototype.copyWithin()`
+ `TypedArray.prototype.every()`
+ `TypedArray.prototype.fill()`
+ `TypedArray.prototype.filter()`
+ `TypedArray.prototype.find()`
+ `TypedArray.prototype.findIndex()`
+ `TypedArray.prototype.forEach()`
+ `TypedArray.prototype.includes()`
+ `TypedArray.prototype.indexOf()`
+ `TypedArray.prototype.join()`
+ `TypedArray.prototype.lastIndexOf()`
+ `TypedArray.prototype.map()`
+ `TypedArray.prototype.reduce()`
+ `TypedArray.prototype.reduceRight()`
+ `TypedArray.prototype.reverse()`
+ `TypedArray.prototype.some()`
+ `TypedArray.prototype.set()`
+ `TypedArray.prototype.slice()`
+ `TypedArray.prototype.sort()`
+ `TypedArray.prototype.subarray()`
+ `TypedArray.prototype.toString()`
**注記**  
`TypedArray.prototype.every()`、`TypedArray.prototype.fill()`、`TypedArray.prototype.filter()`、`TypedArray.prototype.find()`、`TypedArray.prototype.findIndex()`、`TypedArray.prototype.forEach()`、`TypedArray.prototype.includes()`、`TypedArray.prototype.indexOf()`、`TypedArray.prototype.join()`、`TypedArray.prototype.lastIndexOf()`、`TypedArray.prototype.map()`、`TypedArray.prototype.reduce()`、`TypedArray.prototype.reduceRight()`、`TypedArray.prototype.reverse()`、および `TypedArray.prototype.some()` は JavaScript ランタイム 2.0 で新しく追加されました。

**ArrayBuffer**  
ArrayBuffer について以下の ES 6 メソッドがサポートされています。  
+ `isView()`
ArrayBuffer について以下の ES 6 プロトタイプメソッドがサポートされています。  
+ `ArrayBuffer.prototype.slice()`

**promise**  
Promise について以下の ES 6 メソッドがサポートされています。  
+ `Promise.all()`
+ `Promise.allSettled()`
+ `Promise.any()`
+ `Promise.reject()`
+ `Promise.resolve()`
+ `Promise.race()`
**注記**  
`Promise.all()`、`Promise.allSettled()`、`Promise.any()`、`Promise.race()` は JavaScript ランタイム 2.0 で新しく追加されました。
Promise について以下の ES 6 プロトタイプメソッドがサポートされています。  
+ `Promise.prototype.catch()`
+ `Promise.prototype.finally()`
+ `Promise.prototype.then()`

**DataView**  
以下の ES 6 プロトタイプメソッドがサポートされています。  
+ `DataView.prototype.getFloat32()`
+ `DataView.prototype.getFloat64()`
+ `DataView.prototype.getInt16()`
+ `DataView.prototype.getInt32()`
+ `DataView.prototype.getInt8()`
+ `DataView.prototype.getUint16()`
+ `DataView.prototype.getUint32()`
+ `DataView.prototype.getUint8()`
+ `DataView.prototype.setFloat32()`
+ `DataView.prototype.setFloat64()`
+ `DataView.prototype.setInt16()`
+ `DataView.prototype.setInt32()`
+ `DataView.prototype.setInt8()`
+ `DataView.prototype.setUint16()`
+ `DataView.prototype.setUint32()`
+ `DataView.prototype.setUint8()`
**注記**  
Dataview ES 6 のプロトタイプメソッドはすべて JavaScript ランタイム 2.0 で新しく追加されました。

**記号**  
以下の ES 6 メソッドがサポートされています。  
+ `Symbol.for()`
+ `Symbol.keyfor()`
**注記**  
Symbol ES 6 メソッドはすべて JavaScript ランタイム 2.0 で新しく追加されました。

**テキストデコーダー**  
以下のプロトタイプメソッドがサポートされています。  
+ `TextDecoder.prototype.decode()`
以下のプロトタイプアクセサプロパティがサポートされています。  
+ `TextDecoder.prototype.encoding`
+ `TextDecoder.prototype.fatal`
+ `TextDecoder.prototype.ignoreBOM`

**テキストエンコーダー**  
以下のプロトタイプメソッドがサポートされています。  
+ `TextEncoder.prototype.encode()`
+ `TextEncoder.prototype.encodeInto()`

## エラーのタイプ
<a name="writing-functions-javascript-features-error-types-20"></a>

以下のエラーオブジェクトがサポートされています。
+ `Error`
+ `EvalError`
+ `InternalError`
+ `RangeError`
+ `ReferenceError`
+ `SyntaxError`
+ `TypeError`
+ `URIError`

## Globals
<a name="writing-functions-javascript-features-globals-20"></a>

`globalThis` オブジェクトはサポートされています。

以下の ES 5.1 グローバル関数がサポートされています。
+ `decodeURI()`
+ `decodeURIComponent()`
+ `encodeURI()`
+ `encodeURIComponent()`
+ `isFinite()`
+ `isNaN()`
+ `parseFloat()`
+ `parseInt()`

以下の ES 6 グローバル関数がサポートされています。
+ `atob()`
+ `btoa()`
**注記**  
`atob()` および `btoa()` は JavaScript ランタイム 2.0 で新しく追加されました。

以下のグローバル定数がサポートされています。
+ `NaN`
+ `Infinity`
+ `undefined`
+ `arguments`

## ビルトインモジュール
<a name="writing-functions-javascript-features-builtin-modules-20"></a>

以下のビルトインモジュールがサポートされています。

**Topics**
+ [バッファ](#writing-functions-javascript-features-builtin-modules-buffer-20)
+ [クエリ文字列](#writing-functions-javascript-features-builtin-modules-query-string-20)
+ [Crypto](#writing-functions-javascript-features-builtin-modules-crypto-20)

### バッファ
<a name="writing-functions-javascript-features-builtin-modules-buffer-20"></a>

このモジュールは、以下のメソッドを提供します。
+ `Buffer.alloc(size[, fill[, encoding]])`

  `Buffer` を割り当てます。
  + `size`: バッファサイズ。整数を入力します。
  + `fill`: オプション。文字列、`Buffer`、Uint8Array または整数を入力します。デフォルトは `0` です。
  + `encoding`: オプション。`fill` が文字列である場合は、`utf8`、`hex`、`base64`、`base64url` のいずれかを入力します。デフォルトは `utf8` です。
+ `Buffer.allocUnsafe(size)`

  初期化されていない `Buffer` を割り当てます。
  + `size`: 整数を入力します。
+ `Buffer.byteLength(value[, encoding])`

  値の長さをバイト単位で返します。
  + `value`: 文字列、`Buffer`、TypedArray、Dataview、または Arraybuffer。
  + `encoding`: オプション。`value` が文字列である場合は、`utf8`、`hex`、`base64`、`base64url` のいずれかを入力します。デフォルトは `utf8` です。
+ `Buffer.compare(buffer1, buffer2)`

  2 つの `Buffer` を比較すると、配列をソートしやすくなります。両者が同じ場合は `0`、`buffer1` が先に来る場合は `-1`、`buffer2` が先に来る場合は `1` を返します。
  + `buffer1`: `Buffer` を入力します。
  + `buffer2`: 別の `Buffer` 値を入力します。
+ `Buffer.concat(list[, totalLength])`

  複数の `Buffer` を連結します。ない場合は `0` を返します。`totalLength` までの値を返します。
  + `list`: `Buffer` のリストを入力します。これは `totalLength` に切り捨てられることに注意してください。
  + `totalLength`: オプション。符号なし整数を入力します。空欄の場合はリスト内の `Buffer` インスタンス総数を使用します。
+ `Buffer.from(array)`

  配列から `Buffer` を作成します。
  + `array`: `0` から `255` までのバイト配列を入力します。
+ `Buffer.from(arrayBuffer, byteOffset[, length]))`

  オフセット `byteOffset` から始めて長さが `length` のビューを `arrayBuffer` から作成します。
  + `arrayBuffer`: `Buffer` 配列を入力します。
  + `byteOffset`: 整数を入力します。
  + `length`: オプション。整数を入力します。
+ `Buffer.from(buffer)`

  `Buffer` のコピーを作成します。
  + `buffer`: `Buffer` を入力します。
+ `Buffer.from(object[, offsetOrEncoding[, length]])`

  オブジェクトから `Buffer` を作成します。`valueOf()` がオブジェクトと等しくない場合は `Buffer.from(object.valueOf(), offsetOrEncoding, length)` を返します。
  + `object`: オブジェクトを入力します。
  + `offsetOrEncoding`: オプション。整数またはエンコーディング文字列を入力します。
  + `length`: オプション。整数を入力します。
+ `Buffer.from(string[, encoding])`

  文字列から `Buffer` を作成します。
  + `string`: 文字列を入力します。
  + `encoding`: オプション。`utf8`、`hex`、`base64`、`base64url` のいずれかを入力します。デフォルトは `utf8` です。
+ `Buffer.isBuffer(object)`

  `object` がバッファかどうかをチェックします。`true` または `false` を返します。
  + `object`: オブジェクトを入力します。
+ `Buffer.isEncoding(encoding)`

  `encoding` がサポートされているかをチェックします。`true` または `false` を返します。
  + `encoding`: オプション。`utf8`、`hex`、`base64`、`base64url` のいずれかを入力します。デフォルトは `utf8` です。

このモジュールは、以下のバッファプロトタイプメソッドを提供します。
+ `Buffer.prototype.compare(target[, targetStart[, targetEnd[, sourceStart[, sourceEnd]]]])`

  ターゲットと `Buffer` を比較します。両者が同じ場合は `0`、`buffer` が先に来る場合は `1`、`target` が先に来る場合は `-1` を返します。
  + `target`: `Buffer` を入力します。
  + `targetStart`: オプション。整数を入力します。デフォルトは 0 です。
  + `targetEnd`: オプション。整数を入力します。デフォルトは `target` の長さです。
  + `sourceStart`: オプション。整数を入力します。デフォルトは 0 です。
  + `sourceEnd`: オプション。整数を入力します。デフォルトは `Buffer` の長さです。
+ `Buffer.prototype.copy(target[, targetStart[, sourceStart[, sourceEnd]]])`

  バッファを `target` にコピーします。
  + `target`: `Buffer` または `Uint8Array` を入力します。
  + `targetStart`: オプション。整数を入力します。デフォルトは 0 です。
  + `sourceStart`: オプション。整数を入力します。デフォルトは 0 です。
  + `sourceEnd`: オプション。整数を入力します。デフォルトは `Buffer` の長さです。
+ `Buffer.prototype.equals(otherBuffer)`

  `Buffer` と `otherBuffer` を比較します。`true` または `false` を返します。
  + `otherBuffer`: 文字列を入力します。
+ `Buffer.prototype.fill(value[, offset[, end][, encoding])`

  `value` に `Buffer` を入力します。
  + `value`: 文字列、`Buffer`、または整数を入力します。
  + `offset`: オプション。整数を入力します。
  + `end`: オプション。整数を入力します。
  + `encoding`: オプション。`utf8`、`hex`、`base64`、`base64url` のいずれかを入力します。デフォルトは `utf8` です。
+ `Buffer.prototype.includes(value[, byteOffset][, encoding])`

  `value` で `Buffer` を検索します。`true` または `false` を返します。
  + `value`: 文字列、`Buffer`、`Uint8Array`、または整数を入力します。
  + `byteOffset`: オプション。整数を入力します。
  + `encoding`: オプション。`utf8`、`hex`、`base64`、`base64url` のいずれかを入力します。デフォルトは `utf8` です。
+ `Buffer.prototype.indexOf(value[, byteOffset][, encoding])`

  `Buffer` で最初の `value` を検索します。見つかった場合は `index` を返し、見つからなかった場合は `-1` を返します。
  + `value`: 文字列、`Buffer`、Unit8Array、または 0 から 255 までの整数を入力します。
  + `byteOffset`: オプション。整数を入力します。
  + `encoding`: オプション。`value` が文字列の場合、`utf8`、`hex`、`base64`、`base64url` のいずれかを入力します。デフォルトは `utf8` です。
+ `Buffer.prototype.lastIndexOf(value[, byteOffset][, encoding])`

  `Buffer` で最後の `value` を検索します。見つかった場合は `index` を返し、見つからなかった場合は `-1` を返します。
  + `value`: 文字列、`Buffer`、Unit8Array、または 0 から 255 までの整数を入力します。
  + `byteOffset`: オプション。整数を入力します。
  + `encoding`: オプション。`value` が文字列の場合、`utf8`、`hex`、`base64`、`base64url` のいずれかを入力します。デフォルトは `utf8` です。
+ `Buffer.prototype.readInt8(offset)`

  `Buffer` から `offset` で `Int8` を読み込みます。
  + `offset`: 整数を入力します。
+ `Buffer.prototype.readIntBE(offset, byteLength)`

  `Buffer` から `offset` で `Int` をビッグエンディアンとして読み取ります。
  + `offset`: 整数を入力します。
  + `byteLength`: オプション。`1` から `6` までの整数を入力します。
+ `Buffer.prototype.readInt16BE(offset)`

  `Buffer` から `offset` で `Int16` をビッグエンディアンとして読み取ります。
  + `offset`: 整数を入力します。
+ `Buffer.prototype.readInt32BE(offset)`

  `Buffer` から `offset` で `Int32` をビッグエンディアンとして読み取ります。
  + `offset`: 整数を入力します。
+ `Buffer.prototype.readIntLE(offset, byteLength)`

  `Buffer` から `offset` で `Int` をリトルエンディアンとして読み取ります。
  + `offset`: 整数を入力します。
  + `byteLength`: `1` から `6` までの整数を入力します。
+ `Buffer.prototype.readInt16LE(offset)`

  `Buffer` から `offset` で `Int16` をリトルエンディアンとして読み取ります。
  + `offset`: 整数を入力します。
+ `Buffer.prototype.readInt32LE(offset)`

  `Buffer` から `offset` で `Int32` をリトルエンディアンとして読み取ります。
  + `offset`: 整数を入力します。
+ `Buffer.prototype.readUInt8(offset)`

  `Buffer` から `offset` で `UInt8` を読み込みます。
  + `offset`: 整数を入力します。
+ `Buffer.prototype.readUIntBE(offset, byteLength)`

  `Buffer` から `offset` で `UInt` をビッグエンディアンとして読み取ります。
  + `offset`: 整数を入力します。
  + `byteLength`: `1` から `6` までの整数を入力します。
+ `Buffer.prototype.readUInt16BE(offset)`

  `Buffer` から `offset` で `UInt16` をビッグエンディアンとして読み取ります。
+ 
  + `offset`: 整数を入力します。
+ `Buffer.prototype.readUInt32BE(offset)`

  `Buffer` から `offset` で `UInt32` をビッグエンディアンとして読み取ります。
  + `offset`: 整数を入力します。
+ `Buffer.prototype.readUIntLE(offset, byteLength)`

  `Buffer` から `offset` で `UInt` をリトルエンディアンとして読み取ります。
  + `offset`: 整数を入力します。
  + `byteLength`: `1` から `6` までの整数を入力します。
+ `Buffer.prototype.readUInt16LE(offset)`

  `Buffer` から `offset` で `UInt16` をリトルエンディアンとして読み取ります。
  + `offset`: 整数を入力します。
+ `Buffer.prototype.readUInt32LE(offset)`

  `Buffer` から `offset` で `UInt32` をリトルエンディアンとして読み取ります。
  + `offset`: 整数を入力します。
+ `Buffer.prototype.readDoubleBE([offset])`

  `Buffer` から `offset` で 64 ビットダブルをビッグエンディアンとして読み込みます。
  + `offset`: オプション。整数を入力します。
+ `Buffer.prototype.readDoubleLE([offset])`

  `Buffer` から `offset` で 64 リトルダブルをビッグエンディアンとして読み込みます。
  + `offset`: オプション。整数を入力します。
+ `Buffer.prototype.readFloatBE([offset])`

  `Buffer` から `offset` で 32 ビットフロートをビッグエンディアンとして読み込みます。
  + `offset`: オプション。整数を入力します。
+ `Buffer.prototype.readFloatLE([offset])`

  `Buffer` から `offset` で 32 ビットフロートをリトルエンディアンとして読み込みます。
  + `offset`: オプション。整数を入力します。
+ `Buffer.prototype.subarray([start[, end]])`

  オフセットし、新しい `start` および `end` で切り取った `Buffer` のコピーを返します。
  + `start`: オプション。整数を入力します。デフォルトは 0 です。
  + `end`: オプション。整数を入力します。デフォルトはバッファの長さです。
+ `Buffer.prototype.swap16()`

  `Buffer` 配列のバイト順を入れ替え、16 ビットの数値の配列として扱います。`Buffer` の長さは 2 で割り切れる必要があります。そうしないと、エラーになります。
+ `Buffer.prototype.swap32()`

  `Buffer` 配列のバイト順を入れ替え、32 ビットの数値の配列として扱います。`Buffer` の長さは 4 で割り切れる必要があります。そうしないと、エラーになります。
+ `Buffer.prototype.swap64()`

  `Buffer` 配列のバイト順を入れ替え、64 ビットの数値の配列として扱います。`Buffer` の長さは 8 で割り切れる必要があります。そうしないと、エラーになります。
+ `Buffer.prototype.toJSON()`

  JSON として `Buffer` を返します。
+ `Buffer.prototype.toString([encoding[, start[, end]]])`

  `start` から `end` まで `Buffer` をエンコードされた文字列に変換します。
  + `encoding`: オプション。`utf8`、`hex`、`base64`、`base64url` のいずれかを入力します。デフォルトは `utf8` です。
  + `start`: オプション。整数を入力します。デフォルトは 0 です。
  + `end`: オプション。整数を入力します。デフォルトはバッファの長さです。
+ `Buffer.prototype.write(string[, offset[, length]][, encoding])`

  スペースがある場合はエンコードされた `string` を `Buffer` に書き込み、十分なスペースがない場合は切り捨てられた `string` になります。
  + `string`: 文字列を入力します。
  + `offset`: オプション。整数を入力します。デフォルトは 0 です。
  + `length`: オプション。整数を入力します。デフォルトは文字列の長さです。
  + `encoding`: オプション。オプションで、`utf8`、`hex`、`base64`、または `base64url` のいずれかを入力します。デフォルトは `utf8` です。
+ `Buffer.prototype.writeInt8(value, offset, byteLength)`

  `offset` で `byteLength` の `Int8` `value` を `Buffer` に書き込みます。
  + `value`: 整数を入力します。
  + `offset`: 整数を入力します
  + `byteLength`: `1` から `6` までの整数を入力します。
+ `Buffer.prototype.writeIntBE(value, offset, byteLength)`

  ビッグエンディアンを使用して `offset` の `value` を `Buffer` に書き込みます。
  + `value`: 整数を入力します。
  + `offset`: 整数を入力します
  + `byteLength`: `1` から `6` までの整数を入力します。
+ `Buffer.prototype.writeInt16BE(value, offset, byteLength)`

  ビッグエンディアンを使用して `offset` の `value` を `Buffer` に書き込みます。
  + `value`: 整数を入力します。
  + `offset`: 整数を入力します
  + `byteLength`: `1` から `6` までの整数を入力します。
+ `Buffer.prototype.writeInt32BE(value, offset, byteLength)`

  ビッグエンディアンを使用して `offset` の `value` を `Buffer` に書き込みます。
  + `value`: 整数を入力します。
  + `offset`: 整数を入力します
  + `byteLength`: `1` から `6` までの整数を入力します。
+ `Buffer.prototype.writeIntLE(offset, byteLength)`

  リトルエンディアンを使用して `offset` の `value` を `Buffer` に書き込みます。
  + `offset`: 整数を入力します。
  + `byteLength`: `1` から `6` までの整数を入力します。
+ `Buffer.prototype.writeInt16LE(offset, byteLength)`

  リトルエンディアンを使用して `offset` の `value` を `Buffer` に書き込みます。
  + `offset`: 整数を入力します。
  + `byteLength`: `1` から `6` までの整数を入力します。
+ `Buffer.prototype.writeInt32LE(offset, byteLength)`

  リトルエンディアンを使用して `offset` の `value` を `Buffer` に書き込みます。
  + `offset`: 整数を入力します。
  + `byteLength`: `1` から `6` までの整数を入力します。
+ `Buffer.prototype.writeUInt8(value, offset, byteLength)`

  `offset` で `byteLength` の `UInt8` `value` を `Buffer` に書き込みます。
  + `value`: 整数を入力します。
  + `offset`: 整数を入力します
  + `byteLength`: `1` から `6` までの整数を入力します。
+ `Buffer.prototype.writeUIntBE(value, offset, byteLength)`

  ビッグエンディアンを使用して `offset` の `value` を `Buffer` に書き込みます。
  + `value`: 整数を入力します。
  + `offset`: 整数を入力します
  + `byteLength`: `1` から `6` までの整数を入力します。
+ `Buffer.prototype.writeUInt16BE(value, offset, byteLength)`

  ビッグエンディアンを使用して `offset` の `value` を `Buffer` に書き込みます。
  + `value`: 整数を入力します。
  + `offset`: 整数を入力します
  + `byteLength`: `1` から `6` までの整数を入力します。
+ `Buffer.prototype.writeUInt32BE(value, offset, byteLength)`

  ビッグエンディアンを使用して `offset` の `value` を `Buffer` に書き込みます。
  + `value`: 整数を入力します。
  + `offset`: 整数を入力します
  + `byteLength`: `1` から `6` までの整数を入力します。
+ `Buffer.prototype.writeUIntLE(value, offset, byteLength)`

  リトルエンディアンを使用して `offset` の `value` を `Buffer` に書き込みます。
  + `value`: 整数を入力します。
  + `offset`: 整数を入力します
  + `byteLength`: `1` から `6` までの整数を入力します。
+ `Buffer.prototype.writeUInt16LE(value, offset, byteLength)`

  リトルエンディアンを使用して `offset` の `value` を `Buffer` に書き込みます。
  + `value`: 整数を入力します。
  + `offset`: 整数を入力します
  + `byteLength`: `1` から `6` までの整数を入力します。
+ `Buffer.prototype.writeUInt32LE(value, offset, byteLength)`

  リトルエンディアンを使用して `offset` の `value` を `Buffer` に書き込みます。
  + `value`: 整数を入力します。
  + `offset`: 整数を入力します
  + `byteLength`: `1` から `6` までの整数を入力します。
+ `Buffer.prototype.writeDoubleBE(value, [offset])`

  ビッグエンディアンを使用して `offset` の `value` を `Buffer` に書き込みます。
  + `value`: 整数を入力します。
  +  `offset`: オプション。整数を入力します。デフォルトは 0 です。
+ `Buffer.prototype.writeDoubleLE(value, [offset])`

  リトルエンディアンを使用して `offset` の `value` を `Buffer` に書き込みます。
  + `value`: 整数を入力します。
  +  `offset`: オプション。整数を入力します。デフォルトは 0 です。
+ `Buffer.prototype.writeFloatBE(value, [offset])`

  ビッグエンディアンを使用して `offset` の `value` を `Buffer` に書き込みます。
  + `value`: 整数を入力します。
  +  `offset`: オプション。整数を入力します。デフォルトは 0 です。
+ `Buffer.prototype.writeFloatLE(value, [offset])`

  リトルエンディアンを使用して `offset` の `value` を `Buffer` に書き込みます。
  + `value`: 整数を入力します。
  +  `offset`: オプション。整数を入力します。デフォルトは 0 です。

以下のインスタンスメソッドがサポートされています。
+ `buffer[index]`

  `Buffer` `index` でオクテット (バイト) を取得および設定します。
  + `0` から `255` までの数値を取得します。または、`0` から `255` までの数値を設定します。

以下のインスタンスプロパティがサポートされています。
+ `buffer`

  バッファの `ArrayBuffer` オブジェクトを取得します。
+ `byteOffset`

  バッファの `Arraybuffer` オブジェクトの `byteOffset` を取得します。
+ `length`

  バッファのバイト数を取得します。

**注記**  
バッファモジュールメソッドはすべて JavaScript ランタイム 2.0 で新しく追加されました。

### クエリ文字列
<a name="writing-functions-javascript-features-builtin-modules-query-string-20"></a>

**注記**  
[CloudFront Functions イベントオブジェクト](functions-event-structure.md)は、URL クエリ文字列を自動的に解析します。つまり、ほとんどの場合、このモジュールを使用する必要はありません。

クエリ文字列モジュール (`querystring`) は、URL クエリ文字列を解析および書式設定するためのメソッドを提供します。`require('querystring')` を使用してモジュールをロードできます。このモジュールは、以下のメソッドを提供します。

`querystring.escape(string)`  
URL は `string` をエンコードし、エスケープしたクエリ文字列を返します。このメソッドは `querystring.stringify()` で使用するため、直接使用しないでください。

`querystring.parse(string[, separator[, equal[, options]]])`  
クエリ文字列 (`string`) を解析し、オブジェクトを返します。  
`separator` パラメータは、クエリ文字列のキーと値のペアを区切る substring です。デフォルトでは、`&` です。  
`equal` パラメータは、クエリ文字列のキーと値を区切る substring です。デフォルトでは、`=` です。  
`options` パラメータは、以下のキーを持つオブジェクトです。    
`decodeURIComponent function`  
クエリ文字列のパーセントエンコーディングされた文字を decode する関数です。デフォルトでは、`querystring.unescape()` です。  
`maxKeys number`  
解析するキーの最大数。デフォルトでは、`1000` です。キーカウントの制限を解除するには、`0` の値を使用します。
デフォルトでは、クエリ文字列のパーセントエンコーディングされた文字は、UTF-8 エンコーディングを使用していると見なされます。無効な UTF-8 シーケンスは、`U+FFFD` 置換文字に置き換えられます。  
たとえば、次のクエリ文字列の場合:  

```
'name=value&abc=xyz&abc=123'
```
`querystring.parse()`の戻り値は次のとおりです。  

```
{
name: 'value',
abc: ['xyz', '123']
}
```
`querystring.decode()` は のエイリアスです。`querystring.parse()`

`querystring.stringify(object[, separator[, equal[, options]]])`  
`object` をシリアル化し、クエリ文字列を返します。  
`separator` パラメータは、クエリ文字列のキーと値のペアを区切る substring です。デフォルトでは、`&` です。  
`equal` パラメータは、クエリ文字列のキーと値を区切る substring です。デフォルトでは、`=` です。  
`options` パラメータは、以下のキーを持つオブジェクトです。    
`encodeURIComponent function`  
URL-unsafe 文字をクエリ文字列のパーセントエンコーディングに変換するために使用される関数です。デフォルトでは、`querystring.escape()` です。
デフォルトでは、クエリ文字列でパーセントエンコーディングが必要な文字は UTF-8 としてエンコードされます。別のエンコーディングを使用するには、`encodeURIComponent` オプションを指定します。  
以下のコードでの例:  

```
querystring.stringify({ name: 'value', abc: ['xyz', '123'], anotherName: '' });
```
戻り値:  

```
'name=value&abc=xyz&abc=123&anotherName='
```
`querystring.encode()` は のエイリアスです。`querystring.stringify()`

`querystring.unescape(string)`  
指定された `string` 内の URL パーセントエンコーディングされた文字をデコードし、エスケープしていないクエリ文字列を返します。このメソッドは `querystring.parse()`で使用するため、直接使用しないでください。

### Crypto
<a name="writing-functions-javascript-features-builtin-modules-crypto-20"></a>

暗号モジュール (`crypto`) は、標準のハッシュおよびハッシュベースのメッセージ認証コード (HMAC) ヘルパーを提供します。`require('crypto')` を使用してモジュールをロードできます。

**ハッシュメソッド**

`crypto.createHash(algorithm)`  
ハッシュオブジェクトを作成して返します。このハッシュオブジェクトは、指定されたアルゴリズム (`md5`、`sha1`、`sha256` のいずれか) を使用してハッシュダイジェストの生成に使用できます。

`hash.update(data)`  
指定された `data` を使用してハッシュコンテンツを更新します。

`hash.digest([encoding])`  
`hash.update()` を使用して渡されたすべてのデータのダイジェストを計算します。エンコードは `hex`、`base64`、`base64url` のいずれかを使用します。

**HMAC メソッド**

`crypto.createHmac(algorithm, secret key)`  
指定された `algorithm` と `secret key` を使用する HMAC オブジェクトを作成して返します。アルゴリズムは `md5`、`sha1`、`sha256` のいずれかを使用します。

`hmac.update(data)`  
指定された `data` を使用して HMAC コンテンツを更新します 。

`hmac.digest([encoding])`  
`hmac.update()` を使用して渡されたすべてのデータのダイジェストを計算します。エンコードは `hex`、`base64`、`base64url` のいずれかを使用します。

## 制限された機能
<a name="writing-functions-javascript-features-restricted-features-20"></a>

次の JavaScript 言語機能は、セキュリティ上の問題により、サポートされていないか、制限されています。

**動的コード評価**  
動的コード評価はサポートされていません。`eval()`、`Function` 両方のコンストラクタが試行された場合、エラーをスローします。たとえば、`const sum = new Function('a', 'b', 'return a + b')` はエラーをスローします。

**タイマー **  
`setTimeout()`、`setImmediate()`、`clearTimeout()` 関数はサポートされていません。関数実行中に defer または yield する規定はありません。関数は同期的に実行しないと完了できません。

**日付とタイムスタンプ**  
セキュリティ上の理由から、高解像度タイマーにはアクセスできません。現在の時刻を照会するすべての `Date` メソッドは、単一の関数実行の存続期間中は常に同じ値を返します。返されるタイムスタンプは、関数の実行を開始した時刻です。したがって、関数内で経過時間を測定することはできません。

**ファイルシステムへのアクセス**  
ファイルシステムにはアクセスできません。たとえば、Node.js にあるようなファイルシステムアクセス用の `fs` モジュールはありません。

**プロセスへのアクセス**  
プロセスにはアクセスできません。例えば、Node.js にあるような、情報アクセスを処理するための `process` グローバルオブジェクトはありません。

**環境変数**  
環境変数にはアクセスできません。この代わりに、CloudFront KeyValueStore を使用して、CloudFront Functions のための key-value ペアの一元化されたデータストアを作成できます。CloudFront KeyValueStore を使用すると、コード変更をデプロイする必要なく、設定データを動的に更新できます。詳細については、「[Amazon CloudFront KeyValueStore](kvs-with-functions.md)」を参照してください。

**ネットワークアクセス**  
ネットワークコールはサポートされていません。たとえば、XHR、HTTP (S)、ソケットはサポートされていません。

# キーバリューストアのヘルパーメソッド
<a name="functions-custom-methods"></a>

**注記**  
CloudFront Functions からのキーバリューストアのヘルパーメソッド呼び出しは、AWS CloudTrail データイベントをトリガーしません。これらのイベントは CloudTrail イベント履歴には記録されません。詳細については、「[AWS CloudTrail を使用した Amazon CloudFront API コールのログ記録](logging_using_cloudtrail.md)」を参照してください。

このセクションは、[CloudFront キーバリューストア](kvs-with-functions.md)を使用して作成する関数にキー値を含める場合に適用されます。CloudFront Functions には、キーバリューストアから値を読み取る 3 つのヘルパーメソッドを提供するモジュールがあります。

このモジュールを関数コードで使用するには、関数に[キーバリューストアを関連付ける](kvs-with-functions-associate.md)必要があります。

次に、関数コードの最初の行に、以下のステートメントを含めます。

```
import cf from 'cloudfront';
const kvsHandle = cf.kvs();
```



## `get()` 方法
<a name="functions-custom-methods-get"></a>

このメソッドを使用して、指定したキー名のキー値を返します。

**[リクエスト**]

```
get("key", options);
```
+ `key`: 値をフェッチする必要があるキーの名前
+ `options`: 1 つのオプション `format` があります。これにより、関数はデータを正しく解析します。使用できる値:
  + `string`: (デフォルト) UTF8 エンコード
  + `json` 
  + `bytes`: 未加工のバイナリデータバッファ

**リクエストの例**

```
const value = await kvsHandle.get("myFunctionKey", { format: "string"});
```

**応答**

レスポンスは `promise` であり、`options` を使用してリクエストした形式の値に解決されます。デフォルトでは、値は文字列として返されます。

### エラー処理
<a name="error-handling-exists-method"></a>

リクエストしたキーが、関連するキーバリューストアに存在しない場合、`get()` メソッドはエラーを返します。このユースケースを管理するには、コードに `try` および `catch` ブロックを追加できます。

**警告**  
promise コンビネーター (例: `Promise.all`、`Promise.any`、および promise チェーンメソッド (例: `then` および `catch`) を使用すると、関数のメモリ使用量が高くなる可能性があります。関数が[最大関数メモリ](cloudfront-limits.md#limits-functions)クォータを超えると、実行に失敗します。このエラーを回避するには、`await` 構文を順番に使用するか、ループ内で使用して複数の値をリクエストすることをお勧めします。  
**例**  

```
var value1 = await kvs.get('key1');
var value2 = await kvs.get('key2');
```
現在、promise コンビネーターを使用して複数の値を取得しても、次の例のように、パフォーマンスは向上しません。  

```
var values = await Promise.all([kvs.get('key1'), kvs.get('key2'),]);
```

## `exists()` 方法
<a name="functions-custom-methods-exists"></a>

このメソッドを使用して、キーがキーバリューストアに存在するかどうかを確認します。

**[リクエスト**]

```
exists("key");
```

**リクエストの例**

```
const exist = await kvsHandle.exists("myFunctionkey");
```

**応答**

レスポンスは `promise` であり、ブール値 (`true` または `false`) を返します。この値は、キーがキーバリューストアに存在するかどうかを示します。

## `meta()` 方法
<a name="functions-custom-methods-meta"></a>

このメソッドを使用して、キーバリューストアに関するメタデータを返します。

**[リクエスト**]

```
meta();
```

**リクエストの例**

```
const meta = await kvsHandle.meta();
```

**応答**

レスポンスは `promise` で、以下のプロパティを持つオブジェクトに解決されます。
+ `creationDateTime`: キーバリューストアが作成された ISO 8601 形式の日付と時刻。
+ `lastUpdatedDateTime`: キーバリューストアがソースから最後に同期された ISO 8601 形式の日付と時刻。値にはエッジへの伝達時間は含まれていません。
+ `keyCount`: ソースからの最後の同期後の KVS 内のキーの合計数。

**レスポンスの例**

```
{keyCount:3,creationDateTime:2023-11-30T23:07:55.765Z,lastUpdatedDateTime:2023-12-15T03:57:52.411Z}
```

# オリジン変更のヘルパーメソッド
<a name="helper-functions-origin-modification"></a>

このセクションは、CloudFront Functions コード内のリクエストで使用されているオリジンを動的に更新または変更する場合に適用されます。オリジンは、*ビューワーリクエスト* CloudFront Functions でのみ更新できます。CloudFront Functions には、オリジンを動的に更新または変更するためのヘルパーメソッドを提供するモジュールがあります。

このモジュールを使用するには、JavaScript ランタイム 2.0 を使用して CloudFront 関数を作成し、関数コードの最初の行に次のステートメントを含めます。

```
import cf from 'cloudfront';
```

詳細については、「[CloudFront Functions の JavaScript ランタイム 2.0 の機能](functions-javascript-runtime-20.md)」を参照してください。

**注記**  
テスト API およびテストコンソールページでは、オリジンの変更が発生したかどうかをテストしません。ただし、テストにより、関数コードがエラーなしで実行されることが保証されます。

## CloudFront Functions と Lambda@Edge のどちらかを選択する
<a name="origin-modification-considerations"></a>

CloudFront Functions または Lambda@Edge のどちらかを使用してオリジンを更新できます。

CloudFront Functions を使用してオリジンを更新する場合は、*ビューワーリクエスト*イベントトリガーを使用します。つまり、この関数を使用するたびに、このロジックがすべてのリクエストで実行されます。Lambda@Edge を使用する場合、オリジン更新機能は*オリジンリクエスト*イベントトリガーに存在します。つまり、このロジックはキャッシュミス時にのみ実行されます。

どちらを選択するかは、ワークロードと、ディストリビューションでの CloudFront Functions と Lambda@Edge の既存の使用状況に大きく依存します。以下の考慮事項は、CloudFront Functions と Lambda@Edge のどちらを使用してオリジンを更新するかを決定するのに役立ちます。

CloudFront Functions は、以下の場合に最も役立ちます。
+ リクエストが動的である (つまりキャッシュできない) ため、常にオリジンに送信される場合。CloudFront Functions は、パフォーマンスを向上させ、全体的なコストを削減します。
+ すべてのリクエストで動作する既存のビューワーリクエスト CloudFront 関数が既にある場合。オリジン更新ロジックを既存の関数内に追加できます。

CloudFront Functions を使用してオリジンを更新するには、以下のトピックでヘルパーメソッドを参照してください。

Lambda@Edge は、以下の場合に最も役立ちます。
+ 高度にキャッシュ可能なコンテンツがある場合。CloudFront Functions はすべてのリクエストで実行されるのに対して、Lambda@Edge はキャッシュミス時にのみ実行されるため、コスト効率が向上します。
+ 既存のオリジンリクエスト Lambda@Edge 関数が既にある場合。オリジン更新ロジックを既存の関数内に追加できます。
+ オリジン更新ロジックで、Amazon DynamoDB や Amazon S3 など、サードパーティのデータソースからデータを取得する必要がある場合。

Lambda@Edge の詳細については、「[Lambda@Edge を使用してエッジでカスタマイズする](lambda-at-the-edge.md)」を参照してください。

## updateRequestOrigin() メソッド
<a name="update-request-origin-helper-function"></a>

`updateRequestOrigin()` メソッドは、リクエストのオリジン設定を更新するために使用します。このメソッドを使用して、ディストリビューションで既に定義されているオリジンの既存のオリジンプロパティを更新したり、リクエストの新しいオリジンを定義したりできます。これを行うには、変更するプロパティを指定します。

**重要**  
`updateRequestOrigin()` で指定しない設定は、既存のオリジンの設定から*同じ設定*を継承します。

`updateRequestOrigin()` メソッドで設定するオリジンは、任意の HTTP エンドポイントが可能であり、CloudFront ディストリビューション内の既存のオリジンである必要はありません。

**注意事項**  
オリジングループの一部であるオリジンを更新する場合、オリジングループの*プライマリオリジン*のみが更新されます。セカンダリオリジンは変更されません。フェイルオーバー条件に一致する変更されたオリジンからのレスポンスコードは、セカンダリオリジンへのフェイルオーバーをトリガーします。
オリジンタイプを変更し、OAC が有効になっている場合は、`originAccessControlConfig` のオリジンタイプが新しいオリジンタイプと一致することを確認してください。
`updateRequestOrigin()` メソッドを使用して [VPC オリジン](private-content-vpc-origins.md)を更新することはできません。リクエストは失敗します。

**[リクエスト**]

```
updateRequestOrigin({origin properties})
```

`origin properties` には、以下を含めることができます。

**domainName (オプション）**  
オリジンのドメイン名。これを指定しない場合、割り当てられたオリジンのドメイン名が代わりに使用されます。    
**カスタムオリジンの場合**  
DNS ドメイン名 (`www.example.com` など) を指定します。ドメイン名ではコロン (`:`) を使用できません。IP アドレスも使用できません。ドメイン名の最大長は 253 文字です。  
**S3 オリジンの場合**  
Amazon S3 バケットの DNS ドメイン名 (`amzn-s3-demo-bucket.s3.eu-west-1.amazonaws.com` など) を指定します。この名前は最大 128 文字で、すべて小文字であることが必要です。

**hostHeader (オプション、S3 カスタムオリジンでない場合)**  
オリジンにリクエストをするときに使用するホストヘッダー。これを指定しない場合、domainName パラメータの値が使用されます。ホストヘッダーまたはドメイン名パラメータのどちらも指定されていない場合、割り当てられたオリジンのドメイン名が使用されます。また、Forward to Origin (FTO) ポリシーにホストが含まれている場合は、受信リクエストのホストヘッダーが使用されます。ホストヘッダーではコロン (`:`) を使用できません。IP アドレスも使用できません。ホストヘッダーは最大 253 文字です。

**originPath (オプション)**  
リクエストがコンテンツを検索するオリジンのディレクトリパス。パスは、先頭をスラッシュ (/) にする必要があります。末尾をスラッシュ (/) にすることはできません。例えば、`example-path/` で終わることはできません。これを指定しない場合、割り当てられたオリジンのオリジンパスが使用されます。    
**カスタムオリジンの場合**  
パスは URL でエンコードし、255 文字以内で指定する必要があります。

**customHeaders (オプション）**  
各カスタムヘッダーの名前と値のペアを指定することで、カスタムヘッダーをリクエストに含めることができます。形式は、イベント構造のリクエストヘッダーおよびレスポンスヘッダーの形式とは異なります。次のキーと値のペアの構文を使用します。  

```
{"key1": "value1", "key2": "value2", ...}
```
許可されていないヘッダーは追加できません。また、同じ名前のヘッダーを受信リクエストの `headers` にも使用することはできません。関数コードでは、ヘッダー名を小文字にする必要があります。CloudFront Functions がイベントオブジェクトを HTTP リクエストに変換し直すと、ヘッダー名の各単語の先頭文字が大文字になり、各単語がハイフンで区切られます。  
例えば、関数コードが `example-header-name` というヘッダーを追加した場合、CloudFront は、これを HTTP リクエストで `Example-Header-Name` に変換します。詳細については、「[CloudFront でオリジンリクエストに追加できないカスタムヘッダー](add-origin-custom-headers.md#add-origin-custom-headers-denylist)」と「[エッジ関数に対する制限](edge-functions-restrictions.md)」を参照してください。  
これを指定しない場合、割り当てられたオリジンの任意のカスタムヘッダーが使用されます。

**connectionAttempts (オプション）**  
CloudFront がオリジンへの接続を試行する回数。最小値は 1、最大値は 3 です。これを指定しない場合、割り当てられたオリジンの接続試行が使用されます。

**originShield (オプション）**  
これにより、CloudFront Origin Shield を有効化または更新します。Origin Shield を使用すると、オリジンの負荷を軽減できます。詳細については、「[Amazon CloudFront Origin Shield の使用](origin-shield.md)」を参照してください。これを指定しない場合、割り当てられたオリジンの Origin Shield 設定が使用されます。    
**enabled (必須）**  
Origin Shield を有効または無効にするブール式。値として `true` または `false` を使用します。  
**region (有効にする場合は必須）**  
Origin Shield の AWS リージョン。オリジンへのレイテンシーが最も低い AWS リージョンを指定します。リージョン名ではなく、リージョンコードを使用します。例えば、米国東部 (オハイオ) リージョンを指定するには、`us-east-2` を使用します。  
CloudFront Origin Shield を有効にする場合は、AWS リージョンを指定する必要があります。利用可能な AWS リージョンのリストと、オリジンに最適なリージョンを選択する方法については、「[Origin Shield の AWS リージョンを選択する](origin-shield.md#choose-origin-shield-region)」を参照してください。

**originAccessControlConfig (オプション）**  
このオリジンのオリジンアクセスコントロール (OAC) の一意の識別子。オリジンが Amazon S3、Lambda 関数 URL、MediaStore、MediaPackage V2 などの CloudFront OAC をサポートしている場合にのみ使用されます。これを指定しない場合は、割り当てられたオリジンの OAC 設定が使用されます。  
レガシーオリジンアクセスアイデンティティ (OAI) はサポートされていません。詳細については、「[AWS オリジンへのアクセスを制限する](private-content-restricting-access-to-origin.md)」を参照してください。    
**enabled (必須）**  
OAC を有効または無効にするブール式。値として `true` または `false` を使用します。  
**signingBehavior (有効にする場合は必須）**  
CloudFront が署名する (認証情報を追加する) リクエストを指定します。最も一般的なユースケースには `always` を指定します。詳細については、「[オリジンアクセスコントロールの詳細設定](private-content-restricting-access-to-s3.md#oac-advanced-settings-s3)」を参照してください。  
このフィールドには以下の値のいずれかがあります。  
+ `always` - CloudFront はすべてのオリジンリクエストに署名し、ビューワーリクエストの `Authorization` ヘッダーが存在する場合は上書きします。
+ `never` - CloudFront はオリジンリクエストに署名しません。この値は、オリジンのオリジンアクセスコントロールをオフにします。
+ `no-override` - ビューワーリクエストに `Authorization` ヘッダーが含まれていない場合、CloudFront はオリジンリクエストに署名します。ビューワーリクエストに `Authorization` ヘッダーが含まれている場合、CloudFront はオリジンリクエストに署名せず、代わりにビューワーリクエストから `Authorization` ヘッダーを渡します。
**警告**  
ビューワーリクエストから `Authorization` ヘッダーを渡すには、このオリジンアクセスコントロールに関連付けられているオリジンを使用するすべてのキャッシュ動作で、このヘッダーをオリジンリクエストポリシーに追加する必要があります。詳細については、「[ポリシーを使用してオリジンリクエストを制御する](controlling-origin-requests.md)」を参照してください。  
**signingProtocol (有効にする場合は必須）**  
OAC の署名プロトコル。CloudFront でリクエストを署名 (認証) する方法を決定します。唯一の有効な値は `sigv4` です。  
**originType (有効にする場合は必須）**  
この OAC のオリジンのタイプ。有効な値は、`s3`、`mediapackagev2`、`mediastore`、および `lambda` です。

**timeouts (オプション)**  
CloudFront がオリジンからの応答やデータ送信を待機する時間を指定できるタイムアウト。これを指定しない場合、割り当てられたオリジンのタイムアウト設定が使用されます。  
指定されていない限り、これらのタイムアウトはカスタムオリジンと Amazon S3 オリジンの両方をサポートします。  
**readTimeout (オプション)**  
`readTimeout` は、次の両方の値に適用されます。  
+ CloudFront がリクエストをオリジンに転送してからレスポンスを受け取るまでの待機時間 (秒)
+ CloudFront がオリジンからレスポンスのパケットを受け取ってから次のパケットを受け取るまでの待機時間 (秒) 
最小のタイムアウトは 1 秒、最大は 120 秒です。詳細については、「[応答タイムアウト](DownloadDistValuesOrigin.md#DownloadDistValuesOriginResponseTimeout)」を参照してください。  
**responseCompletionTimeout (オプション)**  
CloudFront からオリジンへのリクエストを開いたままにして応答を待機できる時間 (秒単位)。この時間までにオリジンから完全な応答が受信されない場合、CloudFront は接続を終了します。  
`responseCompletionTimeout` の値は、`readTimeout` の値以上にする必要があります。詳細については、「[応答完了タイムアウト](DownloadDistValuesOrigin.md#response-completion-timeout)」を参照してください。  
**keepAliveTimeout (オプション)**  
このタイムアウトはカスタムオリジンにのみ適用され、Amazon S3 オリジンには適用されません (S3 オリジン設定では、これらの設定は無視されます。)   
`keepAliveTimeout` は、レスポンスの最後のパケットを受信した後、CloudFront がオリジンへの接続を維持しようとする時間を指定します。最小のタイムアウトは 1 秒、最大は 120 秒です。詳細については、「[キープアライブタイムアウト (カスタムオリジンおよび VPC オリジンのみ)](DownloadDistValuesOrigin.md#DownloadDistValuesOriginKeepaliveTimeout)」を参照してください。  
**connectionTimeout (オプション）**  
オリジンへの接続を確立しようとするときに CloudFront が待機する秒数。最小のタイムアウトは 1 秒、最大は 10 秒です。詳細については、「[接続タイムアウト](DownloadDistValuesOrigin.md#origin-connection-timeout)」を参照してください。

**customOriginConfig (オプション）**  
`customOriginConfig` を使用して、Amazon S3 バケット*ではない*オリジンの接続設定を指定します。1 つの例外があります。S3 バケットが静的ウェブサイトホスティングで設定されている場合は、これらの設定を指定できます (他のタイプの S3 バケット設定では、これらの設定は無視されます)。`customOriginConfig` を指定しない場合、割り当てられたオリジンの設定が使用されます。    
**port (必須)**  
CloudFront がオリジンに接続するために使用する HTTP ポート。オリジンがリッスンしている HTTP ポートを指定します。  
**protocol (必須)**  
CloudFront がオリジンへの接続に使用するプロトコル (HTTP または HTTPS) を指定します。有効な値は次のとおりです。  
+ `http` – CloudFront は常に HTTP を使用してオリジンに接続します。
+ `https` – CloudFront は常に HTTPS を使用してオリジンに接続します。  
**sslProtocols (必須）**  
HTTPS 経由でオリジンに接続するときに CloudFront で使用する最小の SSL/TLS プロトコルを指定するリスト。有効な値は、`SSLv3`、`TLSv1`、`TLSv1.1`、および `TLSv1.2` です。詳細については、「[最小限のオリジン SSL プロトコル](DownloadDistValuesOrigin.md#DownloadDistValuesOriginSSLProtocols)」を参照してください。  
**ipAddressType (オプション)**  
CloudFront がオリジンへの接続に使用する IP アドレスタイプを指定します。有効な値は、`ipv4`、`ipv6`、および `dualstack` です。`ipAddressType` の変更は、`domainName` プロパティも変更される場合にのみサポートされます。

**sni (オプション、S3 カスタムオリジンでない場合)**  
Server Name Indication (SNI) は、TLS ハンドシェイクプロセスの開始時に接続しようとしているホスト名をクライアントが示す Transport Layer Security (TLS) プロトコルの拡張機能です。この値は、オリジンサーバーの TLS 証明書の共通名と一致している必要があります。それ以外の場合、オリジンサーバーがエラーをスローする可能性があります。  
これを指定しない場合、`hostHeader` パラメータの値が使用されます。ホストヘッダーが指定されない場合、`domainName` パラメータの値が使用されます。  
ホストヘッダーまたはドメイン名パラメータのどちらも指定されていない場合、割り当てられたオリジンのドメイン名が使用されます。また、Forward to Origin (FTO) ポリシーにホストが含まれている場合は、受信リクエストのホストヘッダーが使用されます。SNI ではコロン (`:`) を使用できません。IP アドレスも使用できません。SNI は最大 253 文字です。

**allowedCertificateNames (オプション、S3 カスタムオリジンでない場合)**  
CloudFront が使用する有効な証明書名のリストを含めて、オリジンサーバーとの TLS ハンドシェイク中にオリジンサーバーの TLS 証明書のドメインマッチングを検証できます。このフィールドは有効なドメイン名の配列を想定しており、`*.example.com` などのワイルドカードドメインを含めることができます。  
最大 20 個の許可された証明書名を指定できます。それぞれの証明書名には最大 64 文字を使用できます。

**Example – Amazon S3 リクエストオリジンへの更新**  
次の例では、ビューワーリクエストのオリジンを S3 バケットに変更し、OAC を有効にして、オリジンに送信されたカスタムヘッダーをリセットします。  

```
cf.updateRequestOrigin({
    "domainName" : "amzn-s3-demo-bucket-in-us-east-1.s3.us-east-1.amazonaws.com",
    "originAccessControlConfig": {
        "enabled": true,
        "signingBehavior": "always",
        "signingProtocol": "sigv4",
        "originType": "s3"
    },
    // Empty object resets any header configured on the assigned origin
    "customHeaders": {}
});
```

**Example – Application Load Balancer リクエストオリジンへの更新**  
次の例では、ビューワーリクエストのオリジンを Application Load Balancer オリジンに変更し、カスタムヘッダーとタイムアウトを設定します。  

```
cf.updateRequestOrigin({
    "domainName" : "example-1234567890.us-east-1.elb.amazonaws.com",
    "timeouts": {
        "readTimeout": 30,
        "connectionTimeout": 5
    },
    "customHeaders": {
        "x-stage": "production",
        "x-region": "us-east-1"
    }
});
```

**Example – Origin Shield が有効になっているオリジンへの更新**  
次の例では、ディストリビューションのオリジンで Origin Shield が有効になっています。関数コードは、オリジンに使用されているドメイン名のみを更新し、他のすべてのオプションパラメータを省略します。この場合、Origin Shield パラメータは更新されていないため、Origin Shield は変更されたオリジンドメイン名で引き続き使用されます。  

```
cf.updateRequestOrigin({
    "domainName" : "www.example.com"
});
```

**Example - ホストヘッダー、SNI、および許可された証明書名を更新する**  
ほとんどのユースケースでは、オリジンへのリクエストにこのタイプの変更を使用する必要はありません。これらの値の変更による影響を理解していない限り、これらのパラメータを使用しないでください。
次の例では、ドメイン名、ホストヘッダー、SNI、およびオリジンへのリクエストで許可された証明書を変更します。  

```
cf.updateRequestOrigin({ 
    "domainName": "www.example.com", 
    "hostHeader": "test.example.com", 
    "sni": "test.example.net", 
    "allowedCertificateNames": ["*.example.com", "*.example.net"],
});
```

## selectRequestOriginById() メソッド
<a name="select-request-origin-id-helper-function"></a>

ディストリビューションで既に設定されている別のオリジンを選択して、既存のオリジンを更新するには、`selectRequestOriginById()` を使用します。このメソッドは、更新されたオリジンで定義されているすべての設定を使用します。

このメソッドは、関数の実行時に使用されたのと同じディストリビューションで既に定義されているオリジンのみを受け入れます。オリジンは、オリジンの設定時に定義したオリジン名であるオリジン ID によって参照されます。

ディストリビューション内で VPC オリジンが設定されている場合は、このメソッドを使用してオリジンを VPC オリジンに更新できます。詳細については、「[VPC オリジンを使用したアクセス制限](private-content-vpc-origins.md)」を参照してください。

**注意事項**  
`selectRequestOriginById()` 関数は、相互 TLS (オリジン) が有効になっているオリジンを選択できません。この関数を使用して相互 TLS (オリジン) 対応オリジンを選択しようとすると、検証エラーが発生します。
ユースケースで相互 TLS (オリジン) を使用した動的オリジン選択が必要な場合は、代わりに `updateRequestOrigin()` を使用し、すべてのターゲットオリジンが同じクライアント証明書を使用していることを確認します。

**[リクエスト**]

```
cf.selectRequestOriginById(origin_id, {origin_overrides})
```

前の例では、`origin_id` は、関数を実行しているディストリビューション内のオリジンのオリジン名を指す文字列です。`origin_overrides ` パラメータには、次を含めることができます。

**hostHeader (オプション、S3 カスタムオリジンでない場合)**  
オリジンにリクエストをするときに使用するホストヘッダー。これを指定しない場合、`domainName` パラメータの値が使用されます。  
ホストヘッダーまたはドメイン名パラメータのどちらも指定されていない場合、割り当てられたオリジンのドメイン名が使用されます。また、Forward to Origin (FTO) ポリシーにホストが含まれている場合は、受信リクエストのホストヘッダーが使用されます。ホストヘッダーではコロン (`:`) を使用できません。IP アドレスも使用できません。ホストヘッダーは最大 253 文字です。

**sni (オプション、S3 カスタムオリジンでない場合)**  
Server Name Indication (SNI) は、TLS ハンドシェイクプロセスの開始時に接続しようとしているホスト名をクライアントが示す Transport Layer Security (TLS) プロトコルの拡張機能です。この値は、オリジンサーバーの TLS 証明書の共通名と一致している必要があります。それ以外の場合、オリジンサーバーがエラーをスローする可能性があります。  
これを指定しない場合、`hostHeader` パラメータの値が使用されます。ホストヘッダーが指定されない場合、`domainName` パラメータの値が使用されます。  
ホストヘッダーまたはドメイン名パラメータのどちらも指定されていない場合、割り当てられたオリジンのドメイン名が使用されます。また、Forward to Origin (FTO) ポリシーにホストが含まれている場合は、受信リクエストのホストヘッダーが使用されます。SNI ではコロン (`:`) を使用できません。IP アドレスも使用できません。SNI は最大 253 文字です。

**allowedCertificateNames (オプション、S3 カスタムオリジンでない場合)**  
CloudFront が使用する有効な証明書名のリストを含めて、オリジンサーバーとの TLS ハンドシェイク中にオリジンサーバーの TLS 証明書のドメインマッチングを検証できます。このフィールドは有効なドメイン名の配列を想定しており、`*.example.com` などのワイルドカードドメインを含めることができます。  
最大 20 個の許可された証明書名を指定できます。それぞれの証明書名には最大 64 文字を使用できます。

**[リクエスト**]

```
selectRequestOriginById(origin_id)
```

前の例では、`origin_id` は、関数を実行しているディストリビューション内のオリジンのオリジン名を指す文字列です。

**Example – Amazon S3 リクエストオリジンを選択する**  
次の例では、ディストリビューションに関連付けられたオリジンのリストから `amzn-s3-demo-bucket-in-us-east-1` という名前のオリジンを選択し、`amzn-s3-demo-bucket-in-us-east-1` オリジンの設定をリクエストに適用します。  

```
cf.selectRequestOriginById("amzn-s3-demo-bucket-in-us-east-1");
```

**Example – Application Load Balancer リクエストオリジンを選択する**  
次の例では、ディストリビューションに関連付けられたオリジンのリストから `myALB-prod` という名前の Application Load Balancer オリジンを選択し、`myALB-prod` の設定をリクエストに適用します。  

```
cf.selectRequestOriginById("myALB-prod");
```

**Example - Application Load Balancer リクエストオリジンを選択し、ホストヘッダーを上書きする**  
前の例のように、次の例ではディストリビューションに関連付けられたオリジンのリストから `myALB-prod` という名前の Application Load Balancer オリジンを選択し、`myALB-prod` の設定をリクエストに適用します。ただし、この例では、`origin_overrides` を使用してホストヘッダー値を上書きします。  

```
cf.overrideRequestOrigin("myALB-prod",{ 
        "hostHeader" : "test.example.com"
});
```

## createRequestOriginGroup() メソッド
<a name="create-request-origin-group-helper-function"></a>

`createRequestOriginGroup()` を使用して、高可用性を必要とするシナリオでフェイルオーバー用の[オリジングループ](high_availability_origin_failover.md#concept_origin_groups.creating)として使用する 2 つのオリジンを定義します。

オリジングループには、2 つのオリジン (プライマリとセカンダリ) と指定したフェイルオーバー基準が含まれます。CloudFront でオリジンフェイルオーバーをサポートするオリジングループを作成します。このメソッドを使用してオリジングループを作成または更新する際に、単一のオリジンではなくオリジングループを指定できます。CloudFront は、フェイルオーバー基準を使用して、プライマリオリジンからセカンダリオリジンにフェイルオーバーします。

ディストリビューションに VPC オリジンが設定されている場合は、このメソッドを使用して、VPC オリジンを使用したオリジングループを作成できます。詳細については、「[VPC オリジンを使用したアクセス制限](private-content-vpc-origins.md)」を参照してください。

**注意事項**  
`createRequestOriginGroup()` 関数は、相互 TLS (オリジン) が有効なオリジンを含むオリジングループの作成をサポートしていません。相互 TLS (オリジン) オリジンを持つオリジングループは、CloudFront Functions を介して動的に作成することはできません。
Mutual TLS (オリジン) でオリジンフェイルオーバー機能が必要な場合は、関数で動的に作成するのではなく、CloudFront ディストリビューション設定でオリジングループを直接設定します。

### リクエスト
<a name="create-origin-group-request"></a>

```
createRequestOriginGroup({origin_group_properties})
```

上記の例で、`origin_group_properties` には以下を含めることができます。

**originIds (必須）**  
`origin_ids` の配列。`origin_id` は、関数を実行するディストリビューション内のオリジンのオリジン名を指す文字列です。配列の一部として 2 つのオリジンを指定する必要があります。リストの最初のオリジンはプライマリオリジンで、2 番目のオリジンはフェイルオーバー用のセカンダリオリジンとして機能します。

**originOverrides (オプション)**  
 `{origin_overrides}` パラメータを使用して、いくつかの詳細設定を上書きできます。`origin overrides` には、以下を含めることができます。    
**hostHeader (オプション、S3 カスタムオリジンでない場合)**  
オリジンにリクエストをするときに使用するホストヘッダー。これを指定しない場合、`domainName` パラメータの値が使用されます。  
ホストヘッダーまたはドメイン名パラメータのどちらも指定されていない場合、割り当てられたオリジンのドメイン名が使用されます。また、Forward to Origin (FTO) ポリシーにホストが含まれている場合は、受信リクエストのホストヘッダーが使用されます。ホストヘッダーではコロン (`:`) を使用できません。IP アドレスも使用できません。ホストヘッダーは最大 253 文字です。  
**sni (オプション、S3 カスタムオリジンでない場合)**  
Server Name Indication (SNI) は、TLS ハンドシェイクプロセスの開始時に接続しようとしているホスト名をクライアントが示す Transport Layer Security (TLS) プロトコルの拡張機能です。この値は、オリジンサーバーの TLS 証明書の共通名と一致している必要があり、それ以外の場合、オリジンサーバーがエラーをスローする可能性があります。  
これを指定しない場合、`hostHeader` パラメータの値が使用されます。ホストヘッダーが指定されない場合、`domainName` パラメータの値が使用されます。  
ホストヘッダーまたはドメイン名パラメータのどちらも指定されていない場合、割り当てられたオリジンのドメイン名が使用されます。また、Forward to Origin (FTO) ポリシーにホストが含まれている場合は、受信リクエストのホストヘッダーが使用されます。SNI ではコロン (`:`) を使用できません。IP アドレスも使用できません。SNI は最大 253 文字です。  
**allowedCertificateNames (オプション、S3 カスタムオリジンでない場合)**  
CloudFront が使用する有効な証明書名のリストを含めて、オリジンサーバーとの TLS ハンドシェイク中にオリジンサーバーの TLS 証明書のドメインマッチングを検証できます。このフィールドは有効なドメイン名の配列を想定しており、`*.example.com` などのワイルドカードドメインを含めることができます。  
最大 20 個の許可された証明書名を指定できます。それぞれの証明書名には最大 64 文字を使用できます。

**selectionCriteria (オプション)**  
`default` オリジンフェイルオーバー条件を使用するか、`media-quality-score` ベースのフェイルオーバーロジックを使用するかを選択します。有効な値は次のとおりです。  
+ `default` は、`failoverCriteria` で指定されたステータスコードに基づいてフェイルオーバー基準を使用します。関数で `selectionCriteria` を設定しない場合、`default` が使用されます。
+ `media-quality-score` は、メディア対応ルーティング機能を使用している場合に使用されます。

**failoverCriteria (必須）**  
プライマリオリジンから返されたステータスコードの配列。このステータスコードが返されると、CloudFront はセカンダリオリジンへのフェイルオーバーをトリガーします。既存のオリジングループを上書きすると、この配列はオリジングループの元の設定で設定されたすべてのフェイルオーバーステータスコードを上書きします。  
`media-quality-score` `selectionCriteria` を使用すると、CloudFront はメディア品質スコアに基づいてリクエストのルーティングを試みます。選択されたオリジンがこの配列に設定されているエラーコードを返した場合、CloudFront は他のオリジンにフェイルオーバーします。

**Example – リクエストオリジングループを作成する**  
次の例では、オリジン ID を使用してリクエストのオリジングループを作成します。これらのオリジン ID は、この関数の実行に使用されるディストリビューションのオリジングループ設定から取得されます。  
必要に応じて、`originOverrides` を使用して、`sni`、`hostHeader`、`allowedCertificateNames` のオリジングループ設定を上書きできます。  

```
import cf from 'cloudfront';

function handler(event) {
    cf.createRequestOriginGroup({
        "originIds": [
            {
                "originId": "origin-1",
                "originOverrides": {
                    "hostHeader": "hostHeader.example.com",
                    "sni": "sni.example.com",
                    "allowedCertificateNames": ["cert1.example.com", "cert2.example.com", "cert3.example.com"]
                }
            },
            {
                "originId": "origin-2",
                "originOverrides": {
                    "hostHeader": "hostHeader2.example.com",
                    "sni": "sni2.example.com",
                    "allowedCertificateNames": ["cert4.example.com", "cert5.example.com"]
                }
            }
        ],
        "failoverCriteria": {
            "statusCodes": [500]
        }
    });
    
    event.request.headers['x-hookx'] = { value: 'origin-overrides' };
    return event.request;
}
```

# CloudFront SaaS Manager プロパティのヘルパーメソッド
<a name="saas-specific-logic-function-code"></a>

CloudFront SaaS Manager の次のヘルパー関数を使用して、作成した関数内のマルチテナントディストリビューションの値を取得します。このページの例を使用するには、まず JavaScript ランタイム 2.0 を使用して CloudFront 関数を作成する必要があります。詳細については、[CloudFront Functions の JavaScript ランタイム 2.0 の機能](functions-javascript-runtime-20.md) を参照してください。

**Topics**
+ [接続グループ](#connection-groups-helper-function)
+ [ディストリビューションテナント](#distribution-tenants-helper-functions)

## 接続グループ
<a name="connection-groups-helper-function"></a>

ディストリビューションテナントに関連付けられている接続グループにはドメイン名があります。

この値を取得するには、イベントオブジェクトの `context` サブオブジェクトの `endpoint` フィールドを使用します。

**[リクエスト**]

```
const value = event.context.endpoint;
```

**レスポンス**

レスポンスは、d111111abcdef8.cloudfront.net などの接続グループのドメイン名を含む `string` です。`endpoint` フィールドは、関連付けられた接続グループを持つマルチテナントディストリビューションに対して関数が呼び出された場合にのみ表示されます。詳細については、「[コンテキストオブジェクト](functions-event-structure.md#functions-event-structure-context)」を参照してください。

## ディストリビューションテナント
<a name="distribution-tenants-helper-functions"></a>

CloudFront Functions には、特定のディストリビューションテナント値へのアクセスを提供するモジュールがあります。

このモジュールを使用するには、関数コードの最初の行に、次のステートメントを含めます。

```
import cf from 'cloudfront';
```

次の例は、直接またはネストされた呼び出し関数を介して、`handler` 関数でのみ使用できます。

### `distributionTenant.id` フィールド
<a name="distribution-tenants-field"></a>

このフィールドを使用して、ディストリビューションテナント ID の値を取得します。

**[リクエスト**]

```
const value = cf.distributionTenant.id;
```

**レスポンス**

レスポンスは、`dt_1a2b3c4d5e6f7` などのディストリビューションテナント ID を含む `string` です。

**エラー処理**

関数が標準ディストリビューションに対して呼び出された場合、`distributionTenant.id` フィールドを指定すると `distributionTenant module is not available` 型エラーが返されます。このユースケースを処理するには、コードに `try` および `catch` ブロックを追加できます。

### `distributionTenant.parameters.get()` 方法
<a name="distribution-tenant-parameters-get-method"></a>

このメソッドを使用して、指定したディストリビューションテナントパラメータ名の値を返します。

```
distributionTenant.parameters.get("key");
```

`key`: 値を取得するディストリビューションテナントパラメータ名。

**[リクエスト]**

```
const value = distributionTenant.parameters.get("key");
```

**応答**

レスポンスは、ディストリビューションテナントパラメータの値を含む `string` です。例えば、キー名が `TenantPath` の場合、このパラメータの値は `tenant1` になります。

**エラー処理**

次のエラーが表示される場合があります。
+ 関数が標準ディストリビューションに対して呼び出された場合、`distributionTenant.parameters.get()` メソッドは `distributionTenant module is not available` 型エラーを返します。
+ 指定したディストリビューションテナントパラメータが存在しない場合は、`DistributionTenantParameterKeyNotFound` エラーが返されます。

これらのユースケースを管理するには、コードに `try` および `catch` ブロックを追加できます。

# async および await を使用します。
<a name="async-await-syntax"></a>

CloudFront Functions JavaScript ランタイム関数 2.0 には、`Promise` オブジェクトを処理するための `async` および `await` 構文が用意されています。Promise は遅延した結果を表し、`async` とマークされた関数のキーワード `await` を使用してアクセスできます。さまざまな新しい WebCrypto 関数が Promise を使用しています。

`Promise` オブジェクトの詳細については、「[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)」を参照してください。

**注記**  
次のコードサンプルでは、JavaScript ランタイム 2.0 を使用する必要があります。  
`await` は `async` 関数内でのみ使用できます。`async` 引数とクロージャはサポートされていません。

```
async function answer() {
    return 42;
}

// Note: async, await can be used only inside an async function. async arguments and closures are not supported.

async function handler(event) {
    // var answer_value = answer(); // returns Promise, not a 42 value
    let answer_value = await answer(); // resolves Promise, 42
    console.log("Answer"+answer_value);
    event.request.headers['answer'] = { value : ""+answer_value };
    return event.request;
}
```

次の JavaScript コード例は、`then` チェーンメソッドを使用して Promise を表示する方法を示しています。`catch` を使用してエラーを表示できます。

**警告**  
promise コンビネーター (例: `Promise.all`、`Promise.any`、および promise チェーンメソッド (例: `then` および `catch`) を使用すると、関数のメモリ使用量が高くなる可能性があります。関数が[最大関数メモリ](cloudfront-limits.md#limits-functions)クォータを超えると、実行に失敗します。このエラーを回避するには、`promise` メソッドの代わりに `await` 構文を使用することをお勧めします。

```
async function answer() {
    return 42;
}

async function squared_answer() {
   return answer().then(value => value * value)
} 
// Note: async, await can be used only inside an async function. async arguments and closures are not supported.
async function handler(event) {
    // var answer_value = answer(); // returns Promise, not a 42 value
    let answer_value = await squared_answer(); // resolves Promise, 42
    console.log("Answer"+answer_value);
    event.request.headers['answer'] = { value : ""+answer_value };
    return event.request;
}
```

# CloudFront Functions の CWT サポート
<a name="cwt-support-cloudfront-functions"></a>

このセクションでは、CloudFront Functions での CBOR ウェブトークン (CWT) のサポートについて詳しく説明します。これにより、CloudFront Edge Locations での安全なトークンベースの認証と承認が可能になります。このサポートはモジュールとして提供され、CloudFront Functions でアクセスできます。

このモジュールを使用するには、JavaScript ランタイム 2.0 を使用して CloudFront Functions を作成し、関数コードの最初の行に次のステートメントを含めます。

```
import cf from 'cloudfront';
```

このモジュールに関連付けられたメソッドには、次からアクセスできます (\$1 はモジュール内に存在するさまざまな関数を表すワイルドカードです)。

```
cf.cwt.*
```

詳細については、「[CloudFront Functions の JavaScript ランタイム 2.0 の機能](functions-javascript-runtime-20.md)」を参照してください。

現在、モジュールは HS256 (HMAC-SHA256) アルゴリズムを使用した MAC0 構造のみをサポートし、トークンの最大サイズは 1KB に制限されています。

## トークン構造
<a name="token-structure"></a>

このセクションでは、CWT モジュールで想定されるトークン構造について説明します。モジュールは、トークンが正しくタグ付けされ、識別可能であること (COSE MAC0 など) を想定しています。さらに、トークンの構造については、モジュールは [CBOR Object Signing and Encryption (COSE) [RFC 8152]](https://datatracker.ietf.org/doc/html/rfc8152) によって設定された標準に従います。

```
( // CWT Tag (Tag value: 61) --- optional    
    ( // COSE MAC0 Structure Tag (Tag value: 17) --- required        
        [            
            protectedHeaders,            
            unprotectedHeaders,            
            payload,            
            tag,        
        ]    
    )
)
```

**Example : COSE MAC0 構造を使用する CWT**  

```
61( // CWT tag     
    17( // COSE_MAC0 tag       
        [         
            { // Protected Headers           
                1: 4  // algorithm : HMAC-256-64         
            },         
            { // Unprotected Headers           
                4: h'53796d6d6574726963323536' // kid : Symmetric key id          
            },         
            { // Payload           
                1: "https://iss.example.com", // iss           
                2: "exampleUser", // sub           
                3: "https://aud.example.com", // aud           
                4: 1444064944, // exp           
                5: 1443944944, // nbf           
                6: 1443944944, // iat         
            },         
            h'093101ef6d789200' // tag       
        ]     
    )   
)
```
トークンを生成する場合、CWT タグはオプションです。ただし、COSE 構造タグは必要です。

## validateToken() メソッド
<a name="validatetoken-method"></a>

関数は、指定されたキーを使用して CWT トークンをデコードし、検証します。検証が成功すると、デコードされた CWT トークンが返されます。それ以外の場合は、エラーをスローします。この関数はクレームセットを検証しないことに注意してください。

### リクエスト
<a name="validatetoken-request"></a>

```
cf.cwt.validateToken(token, handlerContext{key})
```パラメータ

**トークン (必須)**  
検証用のエンコードされたトークン。これは JavaScript バッファである必要があります。

**handlerContext (必須)**  
validateToken 呼び出しのコンテキストを保存する JavaScript オブジェクト。現在、 キープロパティのみがサポートされています。

**キー (必須)**  
メッセージダイジェストの計算のシークレットキー。文字列または JavaScript バッファのいずれかとして指定できます。

### 応答
<a name="validatetoken-response"></a>

`validateToken()` メソッドが正常に検証されたトークンを返すと、関数からのレスポンスは次の形式の `CWTObject` になります。デコードされると、すべてのクレームキーが文字列として表されます。

```
CWTObject {    
    protectedHeaders,    
    unprotectedHeaders,    
    payload
}
```

### 例 – トークンの一部として送信された kid を使用してトークンを検証します
<a name="validatetoken-example"></a>

この例では、kid がヘッダーから抽出される CWT トークンの検証を示しています。その後、kid は CloudFront Functions KeyValueStore に渡され、トークンの検証に使用されるシークレットキーを取得します。

```
import cf from 'cloudfront'

const CwtClaims = {
   iss: 1,
   aud: 3,
   exp: 4
}

async function handler(event) {
    try {
        let request = event.request;
        let encodedToken = request.headers['x-cwt-token'].value;
        let kid = request.headers['x-cwt-kid'].value;
                
        // Retrieve the secret key from the kvs
        let secretKey = await cf.kvs().get(kid);
                 
        // Now you can use the secretKey to decode & validate the token.
        let tokenBuffer = Buffer.from(encodedToken, 'base64url');
                
        let handlerContext = {
           key: secretKey,
        }
                
        try {
            let cwtObj = cf.cwt.validateToken(tokenBuffer, handlerContext);
                        
            // Check if token is expired
            const currentTime = Math.floor(Date.now() / 1000); // Current time in seconds
            if (cwtObj[CwtClaims.exp] && cwtObj[CwtClaims.exp] < currentTime) {
                return {
                    statusCode: 401,
                    statusDescription: 'Token expired'
                };
            }
        } catch (error) {
            return {
               statusCode: 401,
               statusDescription: 'Invalid token'
            };
         }
    } catch (error) {
        return {
            statusCode: 402,
            statusDescription: 'Token processing failed'
        };
     }
    return request;
}
```

## generateToken() メソッド
<a name="generatetoken-method"></a>

この関数は、提供されたペイロードとコンテキスト設定を使用して新しい CWT トークンを生成します。

### リクエスト
<a name="generatetoken-request"></a>

```
cf.cwt.generateToken(generatorContext, payload)
```パラメータ

**generatorContext (必須)**  
これは、トークンを生成するためのコンテキストとして使用される JavaScript オブジェクトで、次のキーと値のペアを含みます。    
**cwtTag (オプション)**  
この値はブール値であり、`true` が指定されている場合は `cwtTag` を追加する必要があります。  
**coseTag (必須)**  
COSE タグタイプを指定します。現在のところ、`MAC0` のみサポートされます。  
**キー (必須)**  
メッセージダイジェストを計算するシークレットキー。この値は、文字列または JavaScript `Buffer` のいずれかです。

**ペイロード (必須)**  
エンコード用のトークンペイロード。ペイロードは `CWTObject` 形式である必要があります。

### 応答
<a name="generatetoken-response"></a>

エンコードされたトークンを含む JavaScript バッファを返します。

**Example : CWT トークンを生成する**  

```
import cf from 'cloudfront';

const CwtClaims = {
    iss: 1,
    sub: 2,
    exp: 4
};

const CatClaims = {
    catu: 401,
    catnip: 402,
    catm: 403,
    catr: 404
};

const Catu = {
    host: 1,
    path: 2,
    ext: 3
};

const CatuMatchTypes = {
    prefix_match: 1,
    suffix_match: 2,
    exact_match: 3
};

const Catr = {
    renewal_method: 1,
    next_renewal_time: 2,
    max_uses: 3
};

async function handler(event) {
    try {
        const response = {
            statusCode: 200,
            statusDescription: 'OK',
            headers: {}
        };
        
        const commonAccessToken = {
            protected: {
                1: "5",
            },
            unprotected: {},
            payload: {
                [CwtClaims.iss]: "cloudfront-documentation",
                [CwtClaims.sub]: "cwt-support-on-cloudfront-functions",
                [CwtClaims.exp]: 1740000000,
                [CatClaims.catu]: {
                    [Catu.host]: {
                        [CatuMatchTypes.suffix_match]: ".cloudfront.net"
                    },
                    [Catu.path]: {
                        [CatuMatchTypes.prefix_match]: "/media/live-stream/cf-4k/"
                    },
                    [Catu.ext]: {
                        [CatuMatchTypes.exact_match]: [
                            ".m3u8",
                            ".ts",
                            ".mpd"
                        ]
                    }
                },
                [CatClaims.catnip]: [
                    "[IP_ADDRESS]",
                    "[IP_ADDRESS]"
                ],
                [CatClaims.catm]: [
                    "GET",
                    "HEAD"
                ],
                [CatClaims.catr]: {
                    [Catr.renewal_method]: "header_renewal",
                    [Catr.next_renewal_time]: 1750000000,
                    [Catr.max_uses]: 5
                }
            }
        };
        
        if (!request.headers['x-cwt-kid']) {
            throw new Error('Missing x-cwt-kid header');
        }
        
        const kid = request.headers['x-cwt-kid'].value;
        const secretKey = await cf.kvs().get(kid);
        
        if (!secretKey) {
            throw new Error('Secret key not found for provided kid');
        }
        
        try {
            const genContext = {
                cwtTag: true,
                coseTag: "MAC0",
                key: secretKey
            };
            
            const tokenBuffer = cf.cwt.generateToken(commonAccessToken, genContext);
            response.headers['x-generated-cwt-token'] = { value: tokenBuffer.toString('base64url') };
                        
            return response;
        } catch (tokenError) {
            return {
                statusCode: 401,
                statusDescription: 'Could not generate the token'
            };
        }
    } catch (error) {
        return {
            statusCode: 402,
            statusDescription: 'Token processing failed'
        };
    }
}
```

**Example : 一部のロジックに基づいてトークンを更新する**  

```
import cf from 'cloudfront'

const CwtClaims = {
   iss: 1,
   aud: 3,
   exp: 4
}

async function handler(event) {
    try {
        let request = event.request;
        let encodedToken = request.headers['x-cwt-token'].value;
        let kid = request.headers['x-cwt-kid'].value;
        let secretKey = await cf.kvs().get(kid); // Retrieve the secret key from the kvs
                
        // Now you can use the secretKey to decode & validate the token.
        let tokenBuffer = Buffer.from(encodedToken, 'base64url');
                
        let handlerContext = {
           key: secretKey,
        }
                
        try {
            let cwtJSON = cf.cwt.validateToken(tokenBuffer, handlerContext);
                        
            // Check if token is expired
            const currentTime = Math.floor(Date.now() / 1000); // Current time in seconds
            if (cwtJSON[CwtClaims.exp] && cwtJSON[CwtClaims.exp] < currentTime) {
                // We can regnerate the token and add 8 hours to the expiry time
                cwtJSON[CwtClaims.exp] = Math.floor(Date.now() / 1000) + (8 * 60 * 60);
                                
                let genContext = {
                  coseTag: "MAC0",
                  key: secretKey
                }
                                
                let newTokenBuffer = cf.cwt.generateToken(cwtJSON, genContext);
                 request.headers['x-cwt-regenerated-token'] = newTokenBuffer.toString('base64url');
            }
        } catch (error) {
            return {
               statusCode: 401,
               statusDescription: 'Invalid token'
            };
         }
    }
    catch (error) {
        return {
            statusCode: 402,
            statusDescription: 'Token processing failed'
        };
     }
    return request;
}
```

# 一般的なヘルパーメソッド
<a name="general-helper-methods"></a>

このページでは、CloudFront Functions 内の追加のヘルパーメソッドについて説明します。これらのメソッドを使用するには、JavaScript ランタイム 2.0 を使用して CloudFront 関数を作成します。

```
import cf from 'cloudfront';
```

詳細については、「[CloudFront Functions の JavaScript ランタイム 2.0 の機能](functions-javascript-runtime-20.md)」を参照してください。

## `edgeLocation` メタデータ
<a name="edge-location-metadata"></a>

このメソッドは、`cloudfront` モジュールの使用が必要です。

**注記**  
このメソッドは、ビューワーリクエスト関数にのみ使用できます。ビューワーレスポンス関数の場合、このメソッドは空です。

この JavaScript オブジェクトを使用して、エッジロケーションの空港コード、予想される[リージョナルエッジキャッシュ](HowCloudFrontWorks.md#CloudFrontRegionaledgecaches)リージョン、またはリクエストの処理に使用される CloudFront サーバーの IP アドレスを取得します。このメタデータは、ビューワーリクエストイベントトリガーでのみ使用できます。

```
cf.edgeLocation = {
    name: SEA
    serverIp: 1.2.3.4
    region: us-west-2
}
```

`cf.edgeLocation` オブジェクトには、以下を含めることができます。

**名前**  
リクエストを処理したエッジロケーションの 3 文字の [IATA コード](https://en.wikipedia.org/wiki/IATA_airport_code)。

**serverIp**  
リクエストを処理したサーバーの IPv4 または IPv6 アドレス。

**リージョン**  
キャッシュミスがある場合にリクエストが使用すると*予想される* CloudFront Regional Edge Cache (REC)。予想される REC が使用できず、バックアップ REC がリクエストに使用される場合、この値は更新されません。プライマリ REC と Origin Shield が同じ場所である場合を除き、これには使用されている Origin Shield の場所は含まれません。

**注記**  
CloudFront がオリジンフェイルオーバーを使用するように設定されている場合、CloudFront Functions は 2 回目は呼び出されません。詳細については、「[CloudFront オリジンフェイルオーバーを使用して高可用性を最適化する](high_availability_origin_failover.md)」を参照してください。

## `rawQueryString()` 方法
<a name="raw-query-string-method"></a>

このメソッドに、`cloudFront` モジュールは必要ありません。

`rawQueryString()` メソッドを使用して、解析されていない未変更のクエリ文字列を文字列として取得します。

**[リクエスト**]

```
function handler(event) {
    var request = event.request;
    const qs = request.rawQueryString();
}
```

**レスポンス**

先頭の `?` なしで、受信リクエストの完全なクエリ文字列を文字列値として返します。
+ クエリ文字列はないが、`?` が存在する場合、関数は空の文字列を返します。
+ クエリ文字列がなく、`?` が存在しない場合、関数は `undefined` を返します。

**ケース 1: 完全なクエリ文字列が返された (先頭に `?` なし)**  
受信リクエスト URL: `https://example.com/page?name=John&age=25&city=Boston`  
`rawQueryString()`戻り値 。`"name=John&age=25&city=Boston"`

**ケース 2: 空の文字列が返された (`?` は存在するが、パラメータがない場合)**  
受信リクエスト URL: `https://example.com/page?`  
`rawQueryString()`戻り値 。`""`

**ケース 3: `undefined` が返された (クエリ文字列および `?` なし)**  
受信リクエスト URL: `https://example.com/page`  
`rawQueryString()`戻り値 。`undefined`