

 [适用于 JavaScript 的 AWS SDK V3 API 参考指南](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/)详细描述了 适用于 JavaScript 的 AWS SDK 版本 3 (V3) 的所有 API 操作。

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 将 SDK 配置为 JavaScript
<a name="configuring-the-jssdk"></a>

在使用的 SDK 通过 API 调用 Web 服务之前，必须配置软件开发工具包。 JavaScript 至少，您必须配置以下项：
+ 您将在哪个 AWS 地区申请服务
+ 您的代码如何进行身份验证 AWS

除了这些设置，您可能还必须配置您的 AWS 资源的权限。例如，您可以限制对 Amazon S3 存储桶的访问或者限制 Amazon DynamoDB 表只能进行只读访问。

《[AWS SDKs 和工具参考指南》](https://docs.aws.amazon.com/sdkref/latest/guide/)还包含设置、功能和其他常见的基本概念。 AWS SDKs

本节中的主题介绍如何为 Node.js 配置软件开发工具包并在 Web 浏览器中 JavaScript 运行。 JavaScript 

**Topics**
+ [每个服务的配置](global-config-object.md)
+ [设置 AWS 区域](setting-region.md)
+ [设置凭证](setting-credentials.md)
+ [Node.js 注意事项](node-js-considerations.md)
+ [浏览器脚本注意事项](browser-js-considerations.md)

# 每个服务的配置
<a name="global-config-object"></a>

您可以通过将配置信息传递给服务对象来配置 SDK。

服务级别配置提供了对各项服务的有效控制，使您能够在需求与默认配置不同时更新各项服务对象的配置。

**注意**  
在 2.x 版本中，可以将 适用于 JavaScript 的 AWS SDK 服务配置传递给各个客户端构造函数。但是，这些配置将首先自动合并到全局 SDK 配置 `AWS.config` 的副本中。  
此外，调用 `AWS.config.update({/* params *})` 仅更新在执行更新调用后实例化的服务客户端的配置，而不是任何现有客户端的配置。  
这种行为经常引起混乱，因此很难向仅以向前兼容的方式影响一部分服务客户端的全局对象添加配置。在版本 3 中，不再有由 SDK 管理的全局配置。必须将配置传递至每个实例化的服务客户端。仍然可以在多个客户端之间共享相同的配置，但是该配置不会自动与全局状态合并。

## 设置每个服务的配置
<a name="service-specific-configuration"></a>

您在 SDK 中使用的每项服务均通过服务对象进行访问，该服务对象是该服务 API 的一部分。 JavaScript 例如，要访问 Amazon S3 服务，您需要创建 Amazon S3 服务对象。您可以将特定于某项服务的配置设置指定为该服务对象的构造函数的一部分。

例如，如果您需要访问多个 AWS 区域中的 Amazon EC2 对象，请为每个区域创建一个 Amazon EC2 服务对象，然后相应地设置每个服务对象的区域配置。

```
var ec2_regionA = new EC2({region: 'ap-southeast-2', maxAttempts: 15});
var ec2_regionB = new EC2({region: 'us-west-2', maxAttempts: 15});
```

# 设置 AWS 区域
<a name="setting-region"></a>

 AWS 区域是同一地理区域内的一组命名 AWS 资源。区域的一个例子是 `us-east-1`，即美国东部（弗吉尼亚州北部）区域。在为的 SDK 中创建服务客户端时，您需要指定一个区域， JavaScript 这样 SDK 就可以访问该区域中的服务。有些服务仅在特定区域中提供。

默认情况下，的 SDK JavaScript 不选择区域。但是，您可以使用环境变量或共享配置`config`文件来设置 AWS 区域。

## 在客户端类构造函数中
<a name="setting-region-constructor"></a>

实例化服务对象时，可以将该资源的 AWS 区域指定为客户端类构造函数的一部分，如下所示。

```
const s3Client = new S3.S3Client({region: 'us-west-2'});
```

## 使用环境变量
<a name="setting-region-environment-variable"></a>

您可以使用 `AWS_REGION` 环境变量设置区域。如果您定义了此变量，则的 SDK 会 JavaScript 读取并使用它。

## 使用共享配置文件
<a name="setting-region-config-file"></a>

就像共享凭据文件允许您存储证书以供 SDK 使用一样，您可以将 AWS 区域和其他配置设置保存在名为 `config` SDK 使用的共享文件中。如果将`AWS_SDK_LOAD_CONFIG`环境变量设置为真实值，则 SDK 会在加载`config`文件时 JavaScript 自动搜索文件。保存 `config` 文件的位置取决于您的操作系统：
+ Linux、macOS 或 Unix 用户 - `~/.aws/config`
+ Windows 用户 - `C:\Users\USER_NAME\.aws\config`

如果您还没有共享 `config` 文件，您可以在指定的目录中创建一个。在以下示例中，`config` 文件设置区域和输出格式。

```
[default]
   region=us-west-2
   output=json
```

有关使用共享`config`和`credentials`文件的更多信息，请参阅《工具参考指南》[和《*工具参考指南》中的共享配置AWS SDKs 和*凭据文件](https://docs.aws.amazon.com/sdkref/latest/guide/file-format.html)。

## 设置区域的优先顺序
<a name="setting-region-order-of-precedence"></a>

区域设置的优先顺序如下：

1. 如果将某个区域传递给客户端类构造函数，则使用该区域。

1. 如果在环境变量中设置了某区域，则使用该区域。

1. 否则，将使用共享配置文件中定义的区域。

# 设置凭证
<a name="setting-credentials"></a>

AWS 使用证书来识别谁在呼叫服务以及是否允许访问所请求的资源。

无论是在 Web 浏览器中还是在 Node.js 服务器中运行，您的 JavaScript 代码都必须先获得有效的凭据，然后才能通过 API 访问服务。可以针对每个服务设置凭证，方法是将凭证直接传递给服务对象。

有几种方法可以设置凭证，这些方法在 Node.js 和 Web 浏览器 JavaScript中有所不同。本部分中的主题介绍如何在 Node.js 或 Web 浏览器中设置凭证。在每种情况下，选项以推荐顺序显示。

## 凭证的最佳实践
<a name="credentials-best-practices"></a>

正确设置凭证可确保您的应用程序或浏览器脚本可以访问所需的服务和资源，同时最大限度地减少可能影响关键任务型应用程序或危及敏感数据的安全问题。

设置凭证时应用的一个重要原则是始终授予您的任务所需的最小权限。提供对资源的最小权限并根据需要添加更多权限更安全，而不是提供超过最小权限的权限，因此需要修复以后可能发现的安全问题。例如，除非您需要读取和写入单独的资源（例如 Amazon S3 存储桶或 DynamoDB 表中的对象），否则请将这些权限设置为只读。

有关授予最低权限的更多信息，请参阅《IAM 用户指南》**最佳实践主题中的[授予最低权限](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege)部分。

**Topics**
+ [凭证的最佳实践](#credentials-best-practices)
+ [在 Node.js 中设置凭证](setting-credentials-node.md)
+ [在 Web 浏览器中设置凭证](setting-credentials-browser.md)

# 在 Node.js 中设置凭证
<a name="setting-credentials-node"></a>

我们建议在本地开发且雇主未向其提供身份验证方法的新用户进行设置 AWS IAM Identity Center。有关更多信息，请参阅 [使用 SDK 进行身份验证 AWS](getting-your-credentials.md)。

Node.js 有几种方法可以为 SDK 提供凭证。其中一些方法更安全，而另一些方法则在开发应用程序时可以提供更大的便利。在 Node.js 中获取凭证时，请注意依赖多个源，例如环境变量和您加载的 JSON 文件。您可以更改运行代码的权限，而不会意识到已发生更改。

适用于 JavaScript 的 AWS SDK V3 在 Node.js 中提供了默认的凭证提供者链，因此您无需明确提供凭证提供商。默认[凭证提供程序链](https://docs.aws.amazon.com/sdkref/latest/guide/standardized-credentials.html#credentialProviderChain)会尝试按给定优先级解析来自各种不同源的凭证，直到从其中一个源返回凭证。您可以在此[处](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/Package/-aws-sdk-credential-providers/#fromnodeproviderchain)找到适用于 JavaScript V3 的 SDK 的凭证提供商链。

## 凭证提供程序链
<a name="credchain"></a>

所有 SDKs 人都有一系列地点（或来源）供他们检查，以便获得用于向某人提出请求的有效凭证 AWS 服务。找到有效凭证后，搜索即告停止。这种系统性搜索被称为默认凭证提供程序链。

对于链中的每个步骤，都有不同的设置值的方法。直接在代码中设置值始终优先，然后设置为环境变量，然后在共享 AWS `config`文件中设置。有关更多信息，请参阅《工具参考指南[》*AWS SDKs 和《工具参考指南》*中的设置优先级](https://docs.aws.amazon.com/sdkref/latest/guide/settings-reference.html#precedenceOfSettings)。

《*AWS SDKs 和工具参考指南》*包含有关所有 AWS SDKs 人使用的 SDK 配置设置的信息 AWS CLI。要详细了解如何通过共享 AWS `config`文件配置 SDK，请参阅[共享配置和凭据文件](https://docs.aws.amazon.com/sdkref/latest/guide/file-format.html)。要详细了解如何通过设置环境变量来配置 SDK，请参阅[环境变量支持](https://docs.aws.amazon.com/sdkref/latest/guide/environment-variables.html)。

要进行身份验证 AWS，请按下表所列顺序 适用于 JavaScript 的 AWS SDK 检查凭证提供商。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/sdk-for-javascript/v3/developer-guide/setting-credentials-node.html)

如果您遵循推荐的新用户入门方法，则可以在入门主题的 [使用 SDK 进行身份验证 AWS](getting-your-credentials.md) 中设置 AWS IAM Identity Center 身份验证。其他身份验证方法适用于不同的情况。为避免安全风险，我们建议始终使用短期凭证。有关其他身份验证方法的步骤，请参阅《[和*工具参考指南》中的身份验证AWS SDKs 和*访问权限](https://docs.aws.amazon.com/sdkref/latest/guide/access.html)。

本部分中的主题介绍如何将凭证加载到 Node.js 中。

**Topics**
+ [凭证提供程序链](#credchain)
+ [从 IAM 角色为 Amazon EC2 加载 Node.js 中的凭证](loading-node-credentials-iam.md)
+ [加载 Node.js Lambda 函数的凭证](loading-node-credentials-lambda.md)

# 从 IAM 角色为 Amazon EC2 加载 Node.js 中的凭证
<a name="loading-node-credentials-iam"></a>

如果在 Amazon EC2 实例上运行 Node.js 应用程序，则可以利用 Amazon EC2 的 IAM 角色自动为实例提供凭证。如果将实例配置为使用 IAM 角色，则 SDK 会自动为您的应用程序选择 IAM 凭证，从而无需手动提供凭证。

有关将 IAM 角色添加到 Amazon EC2 实例的更多信息，请参阅[适用于 Amazon EC2 的 IAM 角色](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html)。

# 加载 Node.js Lambda 函数的凭证
<a name="loading-node-credentials-lambda"></a>

创建 AWS Lambda 函数时，必须创建一个有权执行该函数的特殊 IAM 角色。此角色称为*执行角色*。当您设置 Lambda 函数时，您必须指定您创建的 IAM 角色作为相应的执行角色。

执行角色为 Lambda 函数提供运行和调用其他 Web 服务所需的凭证。因此，您不需要为在 Lambda 函数中编写的 Node.js 代码提供凭证。

有关您创建 Lambda 执行角色的更多信息，请参阅《AWS Lambda 开发人员指南》** 中的[管理权限：使用 IAM 角色（执行角色）](https://docs.aws.amazon.com/lambda/latest/dg/intro-permission-model.html#lambda-intro-execution-role)。

# 在 Web 浏览器中设置凭证
<a name="setting-credentials-browser"></a>

有几种方法可以从浏览器脚本为 SDK 提供凭证。其中一些方法更安全，而另一些方法则在开发脚本时可以提供更大的便利。

 下面是按推荐顺序提供凭证的方法：

1. 使用 Amazon Cognito 验证用户身份和提供凭证

1. 使用 Web 联合身份验证

**警告**  
我们不建议在脚本中对您的 AWS 凭证进行硬编码。硬编码凭证存在暴露您的访问密钥 ID 和秘密访问密钥的风险。

**Topics**
+ [使用 Amazon Cognito 身份对用户进行身份验证](loading-browser-credentials-cognito.md)

# 使用 Amazon Cognito 身份对用户进行身份验证
<a name="loading-browser-credentials-cognito"></a>

获取浏览器脚本的 AWS 凭证的推荐方法是使用 Amazon Cognito Identity 凭证客户端 `CognitoIdentityClient`。Amazon Cognito 支持通过第三方身份提供商对用户进行身份验证。

要使用 Amazon Cognito Identity，您必须先在 Amazon Cognito 控制台中创建一个身份池。身份池表示应用程序为用户提供的身份组。为用户提供的身份唯一地标识每个用户账户。Amazon Cognito 身份并不是凭证。可以在 AWS Security Token Service (AWS STS) 中使用 Web 联合身份验证支持为凭证交换这些身份。

Amazon Cognito 可帮助您管理跨多个身份提供商的身份抽象。然后，在 AWS STS 中为凭证交换加载的身份。

## 配置 Amazon Cognito 身份凭证对象
<a name="browser-cognito-configuration"></a>

如果您尚未创建身份池，则在配置 Amazon Cognito 客户端之前，请先创建一个以与 [Amazon Cognito 控制台](https://console.aws.amazon.com/cognito)中的浏览器脚本一起使用。为身份池创建并关联经过身份验证和未经身份验证的 IAM 角色。有关更多信息，请参阅《Amazon Cognito 开发人员指南》**中的[教程：创建身份池](https://docs.aws.amazon.com/cognito/latest/developerguide/tutorial-create-identity-pool.html)。

未经身份验证的用户的身份未经过验证，因此，该角色很适合您的应用程序的来宾用户或用户身份验证与否无关紧要的情形。经过身份验证的用户可以通过证实其身份的第三方身份提供商登录到您的应用程序。确保您的资源的权限范围适当，让未经身份验证的用户无权访问这些资源。

配置身份池后，可使用 `@aws-sdk/credential-providers` 中的 `fromCognitoIdentityPool` 方法从身份池中检索凭证。在以下创建 Amazon S3 客户端的示例中，将 *AWS\$1REGION* 替换为区域，将 *IDENTITY\$1POOL\$1ID* 替换为身份池 ID。

```
// Import required AWS SDK clients and command for Node.js
import {S3Client} from "@aws-sdk/client-s3";
import {fromCognitoIdentityPool} from "@aws-sdk/credential-providers";

const REGION = AWS_REGION;

const s3Client = new S3Client({
  region: REGION,
  credentials: fromCognitoIdentityPool({
    clientConfig: { region: REGION }, // Configure the underlying CognitoIdentityClient.
    identityPoolId: 'IDENTITY_POOL_ID',
    logins: {
            // Optional tokens, used for authenticated login.
        },
  })
});
```

可选的 `logins` 属性是身份提供商名称到这些提供商身份令牌的映射。您如何从身份提供商获得令牌的方式取决于您使用的提供商。例如，如果您使用 Amazon Cognito 用户池作为身份验证提供商，则可以使用类似于以下方法的方法。

```
// Get the Amazon Cognito ID token for the user. 'getToken()' below.
let idToken = getToken();
let COGNITO_ID = "COGNITO_ID"; // 'COGNITO_ID' has the format 'cognito-idp.REGION.amazonaws.com/COGNITO_USER_POOL_ID'
let loginData = {
  [COGNITO_ID]: idToken,
};
const s3Client = new S3Client({
    region: REGION,
    credentials: fromCognitoIdentityPool({
    clientConfig: { region: REGION }, // Configure the underlying CognitoIdentityClient.
    identityPoolId: 'IDENTITY_POOL_ID',
    logins: loginData
  })
});

// Strips the token ID from the URL after authentication.
window.getToken = function () {
  var idtoken = window.location.href;
  var idtoken1 = idtoken.split("=")[1];
  var idtoken2 = idtoken1.split("&")[0];
  var idtoken3 = idtoken2.split("&")[0];
  return idtoken3;
};
```

## 将未经身份验证的用户切换为经过身份验证的用户
<a name="browser-switching-unauthenticated-users"></a>

Amazon Cognito 同时支持经过身份验证的用户和未经身份验证的用户。即使未经身份验证的用户不通过任何身份提供商登录，这些用户也有权访问您的资源。此级别的访问可用于向尚未登录的用户显示内容。即使每个未经身份验证的用户尚未单独登录和经过身份验证，这些用户在 Amazon Cognito 中也都具有唯一的身份。

### 最初未经身份验证的用户
<a name="browser-initially-unauthenticated-user"></a>

用户通常从未经身份验证的角色开始，为此需要设置配置对象的凭证属性而不是 `logins` 属性。在这种情况下，您的默认凭证可能如下所示：

```
// Import the required 适用于 JavaScript 的 AWS SDK v3 modules.                   
import {fromCognitoIdentityPool} from "@aws-sdk/credential-providers";
// Set the default credentials.
const creds = fromCognitoIdentityPool({
  identityPoolId: 'IDENTITY_POOL_ID',
  clientConfig: { region: REGION } // Configure the underlying CognitoIdentityClient.
});
```

### 切换为经过身份验证的用户
<a name="switch-to-authenticated"></a>

当未经身份验证的用户登录身份提供商并且您拥有令牌时，您可以通过调用可更新凭证对象和添加 `logins` 令牌的自定义函数，来将用户从未经身份验证的用户切换为经过身份验证的用户。

```
// Called when an identity provider has a token for a logged in user
function userLoggedIn(providerName, token) {
  creds.params.Logins = creds.params.logins || {};
  creds.params.Logins[providerName] = token;
                    
  // Expire credentials to refresh them on the next request
  creds.expired = true;
}
```

# Node.js 注意事项
<a name="node-js-considerations"></a>

尽管 Node.js 代码是 JavaScript，但 适用于 JavaScript 的 AWS SDK 在 Node.js 中使用可能与在浏览器脚本中使用 SDK 有所不同。一些 API 方法在 Node.js 中有效，但在浏览器脚本以及其他方法中不起作用。成功使用某些模块 APIs 取决于你对常见 Node.js 编码模式的熟悉程度，例如导入和使用其他 Node.js 模块，例如该模`File System (fs)`块。

**注意**  
AWS 建议使用 Active LTS 版本的 Node.js 进行开发。

## 使用内置 Node.js 模块
<a name="node-common-modules"></a>

Node.js 提供了一组内置模块，无需安装即可使用它们。要使用这些模块，请使用 `require` 方法创建一个对象以指定模块名称。例如，要包含内置的 HTTP 模块，请使用以下方法。

```
import http from 'http';
```

调用模块的方法，就好像它们是该对象的方法一样。例如，下面的代码读取您的 HTML 文件。

```
// include File System module
import fs from "fs"; 
// Invoke readFile method 
fs.readFile('index.html', function(err, data) {
  if (err) {
    throw err;
  } else {
    // Successful file read
  }
});
```

有关 Node.js 提供的所有内置模块的完整列表，请参阅 Node.js 网站上的 [Node.js 文档](https://nodejs.org/api/modules.html)。

## 使用 npm 程序包
<a name="node-npm-packages"></a>

除了内置模块，您还可以包含并合并来自 `npm`（即 Node.js 程序包管理器）的第三方代码。这是一个开源 Node.js 程序包的存储库和一个用于安装这些程序包的命令行界面。有关软件包的更多信息`npm`以及当前可用软件包的列表，请参阅[ https://www.npmjs.com](https://www.npmjs.com)。您还可以在[此处](https://github.com/sindresorhus/awesome-nodejs)了解可以使用的其他 Node.js 软件包 GitHub。

# 在 Node.js 中配置 maxSockets
<a name="node-configuring-maxsockets"></a>

在 Node.js 中，您可以设置每个源的最大连接数。如果设置了 ` maxSockets`，则低级 HTTP 客户端会将请求排队，并在它们可用时将它们分配给套接字。

这使您可以设置在某个时间对给定源的并发请求数的上限。降低此值可以减少收到的限制或超时错误的数量。但是，它还会增加内存使用量，因为请求进行排队，直到套接字变为可用状态。

以下示例演示了如何为 DynamoDB 客户端设置 `maxSockets`：

```
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import { NodeHttpHandler } from "@smithy/node-http-handler";
import https from "https";    
let agent = new https.Agent({
  maxSockets: 25
});

let dynamodbClient = new DynamoDBClient({
  requestHandler: new NodeHttpHandler({
    requestTimeout: 3_000,
    httpsAgent: agent
  });
});
```

如果您不提供`maxSockets`值或`Agent`对象，则适用的 SDK 将 JavaScript 使用值 50。如果您提供了 `Agent` 对象，则系统将使用其 `maxSockets` 值。有关在 Node.js 中设置 `maxSockets` 的更多信息，请参阅 [Node.js 文档](https://nodejs.org/dist/latest/docs/api/http.html#http_agent_maxsockets)。

从 v3.521.0 起 适用于 JavaScript 的 AWS SDK，您可以使用以下[速记语法进行配置](https://github.com/aws/aws-sdk-js-v3/blob/main/supplemental-docs/CLIENTS.md#new-in-v35210)。`requestHandler`

```
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";

const client = new DynamoDBClient({
  requestHandler: {
    requestTimeout: 3_000,
    httpsAgent: { maxSockets: 25 },
  },
});
```

# 在 Node.js 中重复使用具有保持连接功能的连接
<a name="node-reusing-connections"></a>

默认的 Node.js HTTP/HTTPS 代理会为每个新请求创建一个新的 TCP 连接。为了避免建立新连接的成本，*默认情况下*会 适用于 JavaScript 的 AWS SDK 重复使用 TCP 连接。

对于短期操作（如 Amazon DynamoDB 查询），设置 TCP 连接的延迟开销可能大于操作本身。此外，由于 Dy [namoDB 静态加密[AWS KMS](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/encryption.howitworks.html)](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/encryption.howitworks.html)与集成，因此您可能会遇到数据库延迟，必须为每个操作重新建立 AWS KMS 新的缓存条目。

如果您不想重复使用 TCP 连接，可以通过 `keepAlive` 在每个服务客户端级别，禁用重复使用这些活跃连接，如以下 DynamoDB 客户端示例所示。

```
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import { NodeHttpHandler } from "@smithy/node-http-handler";
import { Agent } from "https";

const dynamodbClient = new DynamoDBClient({
    requestHandler: new NodeHttpHandler({
        httpsAgent: new Agent({ keepAlive: false })
    })
});
```

如果已启用 `keepAlive`，您还可以使用 `keepAliveMsecs` 设置 TCP Keep-Alive 数据包的初始延迟，默认值为 1000ms。有关详细信息，请参阅 [Node.js 文档](https://nodejs.org/api/http.html#new-agentoptions)。

# 配置 Node.js 的代理
<a name="node-configuring-proxies"></a>

如果您无法直接连接到互联网，则适用的 SDK JavaScript 支持通过第三方 HTTP 代理使用 HTTP 或 HTTPS 代理。

要查找第三方 HTTP 代理，请在 [npm](https://www.npmjs.com/) 上搜索“HTTP 代理”。

要安装第三方 HTTP 代理代理，请在命令提示符下输入以下内容，其中*PROXY*是`npm`软件包的名称。

```
npm install PROXY --save
```

要在应用程序中使用代理，请使用 `httpAgent` 和 ` httpsAgent` 属性，如以下 DynamoDB 客户端示例所示。

```
import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
import { NodeHttpHandler } from "@smithy/node-http-handler";
import { HttpsProxyAgent } from "hpagent";
const agent = new HttpsProxyAgent({ proxy: "http://internal.proxy.com" });
const dynamodbClient = new DynamoDBClient({
    requestHandler: new NodeHttpHandler({
        httpAgent: agent,
        httpsAgent: agent
    }),
});
```

**注意**  
`httpAgent` 与 `httpsAgent`，而且由于来自客户端的大多数调用都是指向 `https`，因此两者都应设置。

# 在 Node.js 中注册证书包
<a name="node-registering-certs"></a>

Node.js 的默认信任存储包含访问 AWS 服务所需的证书。在某些情况下，最好只包括一组特定的证书。

在本示例中，使用磁盘上的特定证书创建 ` https.Agent`，除非提供指定的证书，否则它会拒绝连接。然后，DynamoDB 客户端将使用新创建的 `https.Agent`。

```
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import { NodeHttpHandler } from "@smithy/node-http-handler";
import { Agent } from "https";
import { readFileSync } from "fs";
const certs = [readFileSync("/path/to/cert.pem")];
const agent = new Agent({
  rejectUnauthorized: true,
  ca: certs
});
const dynamodbClient = new DynamoDBClient({
  requestHandler: new NodeHttpHandler({
    httpAgent: agent,
    httpsAgent: agent
  })
});
```

# 浏览器脚本注意事项
<a name="browser-js-considerations"></a>

以下主题描述了 适用于 JavaScript 的 AWS SDK 在浏览器中使用脚本时的特殊注意事项。

**Topics**
+ [为浏览器构建 SDK](building-sdk-for-browsers.md)
+ [跨源资源共享 (CORS)](cors.md)
+ [使用 Webpack 捆绑应用程序](webpack.md)

# 为浏览器构建 SDK
<a name="building-sdk-for-browsers"></a>

与 JavaScript 版本 2 (V2) 的 SDK 不同，V3 不是作为包含默认服务集支持的 JavaScript 文件提供的。取而代之的是，V3 允许您仅在浏览器中捆绑和包含所需 JavaScript 文件的 SDK，从而减少开销。我们建议使用 Webpack 将所需的 JavaScript 文件 SDK 以及您需要的任何其他第三方软件包捆绑到一个`Javascript`文件中，然后使用`<script>`标签将其加载到浏览器脚本中。有关 Webpack 的更多信息，请参阅[使用 Webpack 捆绑应用程序](webpack.md)。

如果您在浏览器中强制执行 CORS 的环境之外使用 SDK，并且想要访问 SDK 为其提供的所有服务 JavaScript，则可以通过克隆存储库并运行与构建 SDK 的默认托管版本相同的构建工具在本地构建 SDK 的自定义副本。下面几部分介绍使用额外服务和 API 版本构建 SDK 的步骤。

## 使用 SDK 生成器构建 SDK JavaScript
<a name="using-the-sdk-builder"></a>

**注意**  
Amazon Web Services 版本 3 (V3) 不再支持浏览器生成器。为了最大限度地减少浏览器应用程序的带宽使用量，我们建议您导入命名模块，然后捆绑它们以减小大小。有关捆绑的更多信息，请参阅[使用 Webpack 捆绑应用程序](webpack.md)。

# 跨源资源共享 (CORS)
<a name="cors"></a>

跨源资源共享（即 CORS）是一项现代 Web 浏览器的安全功能。它使得 Web 浏览器可以协商哪些域能够发出对外部网站或服务的请求。

在使用 适用于 JavaScript 的 AWS SDK 开发浏览器应用程序时，CORS 是一个重要的考虑因素，因为对资源的大部分请求发送到外部域，例如 Web 服务的端点。如果您的 JavaScript 环境实施 CORS 安全性，则必须对该服务配置 CORS。

CORS 根据以下条件，确定是否允许跨源请求中的共享：
+ 发出请求的特定域 
+ 发出的 HTTP 请求的类型（GET、PUT、POST、DELETE 等等）

## CORS 工作原理
<a name="how-cors-works"></a>

在最简单的情况下，浏览器脚本从其他域中的服务器发出对某个资源的 GET 请求。根据该服务器的 CORS 配置，如果请求来自已授权提交 GET 请求的域，则跨来源服务器通过返回请求的资源做出响应。

如果请求域或者 HTTP 请求的类型未获得授权，则将拒绝请求。但是，CORS 实现了在实际提交请求之前进行预检。在这种情况下将提交预检请求，在其中发送 `OPTIONS` 访问请求操作。如果跨来源服务器的 CORS 配置授予对请求域的访问权限，则服务器发送回预检响应，其中列出请求域可以对所请求资源发出的所有 HTTP 请求类型。

![\[CORS 请求的流程流\]](http://docs.aws.amazon.com/zh_cn/sdk-for-javascript/v3/developer-guide/images/cors-overview.png)


## 是否需要 CORS 配置？
<a name="the-need-for-cors-configuration"></a>

Amazon S3 存储桶需要 CORS 配置，然后才能在存储桶上执行操作。在某些 JavaScript 环境中，CORS 可能未实施，因此不需要配置 CORS。例如，如果您在 Amazon S3 存储桶中托管应用程序并访问 `*.s3.amazonaws.com` 或某个其它特定端点的资源，您的请求不会访问外部域。因此，此配置不需要 CORS。在这种情况下，Amazon S3 之外的服务仍使用 CORS。

## 配置 Amazon S3 存储桶的 CORS
<a name="configuring-cors-s3-bucket"></a>

您可以在 Amazon S3 控制台中配置 Amazon S3 存储桶，以使用 CORS。

如果要在 AWS Web Services Management 控制台中配置 CORS，则必须使用 JSON 来创建 CORS 配置。新的 AWS Web Services Management 控制台仅支持 JSON CORS 配置。

**重要**  
在新的 AWS Web Services Management 控制台中，CORS 配置必须是 JSON。

1. 在 AWS Web Services Management 控制台中，打开 Amazon S3 控制台，找到要配置的存储桶，然后选中其复选框。

1. 在打开的窗格中，选择**权限**。

1. 在**权限**选项卡中，选择 **CORS 配置**。

1. 在 **CORS 配置编辑器** 中输入您的 CORS 配置，然后选择**保存**。

CORS 配置是一个 XML 文件，在 `<CORSRule>` 中包含了一系列规则。一个配置最多可以有 100 个规则。规则由以下标签之一定义：
+ `<AllowedOrigin>` - 指定您允许发出跨域请求的域源。
+ `<AllowedMethod>` - 指定您允许在跨域请求中使用的请求类型（GET、PUT、POST、DELETE、HEAD）。
+ `<AllowedHeader>` - 指定预检请求中允许的标头。

有关示例配置，请参阅《Amazon Simple Storage Service 用户指南》**中的[如何在我的存储桶上配置 CORS？](https://docs.aws.amazon.com/AmazonS3/latest/userguide/cors.html#how-do-i-enable-cors)。

## CORS 配置示例
<a name="cors-configuration-example"></a>

以下 CORS 配置示例允许用户从域 `example.org` 中查看、添加、移除或更新存储桶内的对象。不过，我们建议您将 `<AllowedOrigin>` 的范围限定到您的网站域名。您可以指定 `"*"` 以允许任意源。

**重要**  
在新的 S3 控制台中，CORS 配置必须是 JSON。

------
#### [ XML ]

```
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
  <CORSRule>
    <AllowedOrigin>https://example.org</AllowedOrigin>
    <AllowedMethod>HEAD</AllowedMethod>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>PUT</AllowedMethod>
    <AllowedMethod>POST</AllowedMethod>
    <AllowedMethod>DELETE</AllowedMethod>
    <AllowedHeader>*</AllowedHeader>
    <ExposeHeader>ETag</ExposeHeader>
    <ExposeHeader>x-amz-meta-custom-header</ExposeHeader>
  </CORSRule>
</CORSConfiguration>
```

------
#### [ JSON ]

```
[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "HEAD",
            "GET",
            "PUT",
            "POST",
            "DELETE"
        ],
        "AllowedOrigins": [
            "https://www.example.org"
        ],
        "ExposeHeaders": [
             "ETag",
             "x-amz-meta-custom-header"]
    }
]
```

------

此配置不授权用户在存储桶上执行操作。它使浏览器的安全模型允许对 Amazon S3 的请求。必须通过存储桶权限或 IAM 角色权限来配置权限。

您可以使用 `ExposeHeader`，让 SDK 读取从 Amazon S3 返回的响应标头。例如，如果要从 `PUT` 或分段上传读取 `ETag` 标头，则需要在配置中包括 `ExposeHeader` 标签，如上例中所示。SDK 只能访问通过 CORS 配置公开的标头。如果您在对象上设置元数据，则将值作为标头返回并带有 `x-amz-meta-` 前缀，例如 `x-amz-meta-my-custom-header`，并且也必须通过相同的方式公开。

# 使用 Webpack 捆绑应用程序
<a name="webpack"></a>

浏览器脚本或 Node.js 中使用代码模块的 Web 应用程序会创建依赖关系。这些代码模块可能会具有自身的依赖关系，导致您的应用程序需要一组互连的模块才能正常工作。要管理依赖关系，您可以使用 `webpack` 等模块捆绑程序。

`webpack` 模块捆绑程序解析您的应用程序代码，搜索 `import` 或 `require` 语句，创建包含您应用程序所需的全部资产的捆绑。这样可以轻松地通过网页提供资产服务。SDK for JavaScript 可以作为包括在输出包中的依赖项之一包括在 `webpack` 中。

有关 `webpack` 的更多信息，请参阅 GitHub 上的 [webpack 模块捆绑程序](https://webpack.github.io/)。

## 安装 Webpack
<a name="webpack-installing"></a>

要安装 `webpack` 模块捆绑程序，您必须已经安装了 npm（Node.js 程序包管理器）。键入以下命令以安装 `webpack` CLI 和 JavaScript 模块。

```
npm install --save-dev webpack
```

要使用 `path` 模块来处理文件和目录路径（该模块是通过 webpack 自动安装的），您可能需要安装 Node.js `path-browserify` 软件包。

```
npm install --save-dev path-browserify
```

## 配置 Webpack
<a name="webpack-configuring"></a>

默认情况下，webpack 在项目的根目录中搜索名为 `webpack.config.js` 的 JavaScript 文件。此文件指定您的配置选项。以下是 WebPack 版本 5.0.0 及更高版本的 `webpack.config.js` 配置文件示例。

**注意**  
Webpack 配置要求因您安装的 Webpack 版本而异。有关更多信息，请参阅 [Webpack 文档](https://webpack.js.org/configuration/)。

```
// Import path for resolving file paths
var path = require("path");
module.exports = {
  // Specify the entry point for our app.
  entry: [path.join(__dirname, "browser.js")],
  // Specify the output file containing our bundled code.
  output: {
    path: __dirname,
    filename: 'bundle.js'
  },
   // Enable WebPack to use the 'path' package.
   resolve:{
  fallback: { path: require.resolve("path-browserify")}
  }
  /**
  * In Webpack version v2.0.0 and earlier, you must tell 
  * webpack how to use "json-loader" to load 'json' files.
  * To do this Enter 'npm --save-dev install json-loader' at the 
  * command line to install the "json-loader' package, and include the 
  * following entry in your webpack.config.js.
  * module: {
    rules: [{test: /\.json$/, use: use: "json-loader"}]
  }
  **/
};
```

在本示例中，指定 `browser.js` 为*入口点*。*入口点* 是 `webpack` 开始搜索导入的模块所用的文件。输出的文件名指定为 `bundle.js`。此输出文件包含应用程序运行所需的全部 JavaScript。如果入口点中指定的代码导入或需要其它模块（例如 SDK for JavaScript），则将捆绑该代码而无需在配置中指定它。

## 运行 Webpack
<a name="webpack-running"></a>

要生成应用程序以使用 `webpack`，请将以下内容添加到您 `package.json` 文件的 `scripts` 对象。

```
"build": "webpack"
```

以下是演示如何添加 `webpack` 的示例 `package.json` 文件。

```
{
  "name": "aws-webpack",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@aws-sdk/client-iam": "^3.32.0",
    "@aws-sdk/client-s3": "^3.32.0"
  },
  "devDependencies": {
    "webpack": "^5.0.0"
  }
}
```

要生成应用程序，请输入以下命令。

```
npm run build
```

随后，`webpack` 模块捆绑程序生成您在项目的根目录中指定的 JavaScript 文件。

## 使用 Webpack 捆绑
<a name="webpack-using-bundle"></a>

要在浏览器脚本中使用捆绑，您可以使用 `<script>` 标签整合捆绑，如下例中所示。

```
<!DOCTYPE html>
<html>
    <head>
        <title>Amazon SDK with webpack</title>
    </head> 
    <body>
        <div id="list"></div>
        <script src="bundle.js"></script>
    </body>
</html>
```

## 适用于 Node.js 的捆绑
<a name="webpack-nodejs-bundles"></a>

您可以通过在配置中将 `node` 指定为目标，使用 `webpack` 生成在 Node.js 中运行的捆绑。

```
target: "node"
```

在磁盘空间有限的环境中运行 Node.js 应用程序时，这非常有用。此处是将 Node.js 指定为输出目标的示例 `webpack.config.js` 配置。

```
// Import path for resolving file paths
var path = require("path");
module.exports = {
  // Specify the entry point for our app.
  entry: [path.join(__dirname, "browser.js")],
  // Specify the output file containing our bundled code.
  output: {
    path: __dirname,
    filename: 'bundle.js'
  },
  // Let webpack know to generate a Node.js bundle.
  target: "node",
   // Enable WebPack to use the 'path' package.
   resolve:{
  fallback: { path: require.resolve("path-browserify")}
   /**
   * In Webpack version v2.0.0 and earlier, you must tell 
   * webpack how to use "json-loader" to load 'json' files.
   * To do this Enter 'npm --save-dev install json-loader' at the 
   * command line to install the "json-loader' package, and include the 
   * following entry in your webpack.config.js.
   module: {
    rules: [{test: /\.json$/, use: use: "json-loader"}]
  }
  **/
};
```