

适用于 JavaScript 的 AWS SDK v2 已终止支持。建议您迁移到 [适用于 JavaScript 的 AWS SDK v3](https://docs.aws.amazon.com//sdk-for-javascript/v3/developer-guide/)。有关更多详情和如何迁移的信息，请参阅本[公告](https://aws.amazon.com/blogs//developer/announcing-end-of-support-for-aws-sdk-for-javascript-v2/)。

# 从浏览器查看 Amazon S3 存储桶中的照片
<a name="s3-example-photos-view"></a>

![\[JavaScript code example that applies to browser execution\]](http://docs.aws.amazon.com/zh_cn/sdk-for-javascript/v2/developer-guide/images/browsericon.png)

**此浏览器脚本代码示例演示：**
+ 如何在 Amazon Simple Storage Service（Amazon S3）桶中创建相册并允许未验证身份用户查看照片。

## 情景
<a name="s3-example-photos-view-scenario"></a>

本示例通过简单的 HTML 页面提供了一个用于查看相册中的照片的基于浏览器的应用程序。相册位于一个作为照片上传目标的 Amazon S3 桶中。

![\[浏览器脚本中的 JavaScript，它将 Amazon S3 桶用于存储相册。\]](http://docs.aws.amazon.com/zh_cn/sdk-for-javascript/v2/developer-guide/images/s3-photo-album-example.png)


浏览器脚本使用 SDK for JavaScript 与 Amazon S3 桶交互。该脚本使用 Amazon S3 客户端类的 [https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#listObjects-property](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#listObjects-property) 方法来允许您查看相册。

## 先决条件任务
<a name="s3-example-photos-view-scenario-prerequisites"></a>

要设置和运行此示例，请先完成以下任务。

**注意**  
在本示例中，您必须对 Amazon S3 桶和 Amazon Cognito 身份池使用相同的 AWS 区域。

### 创建存储桶
<a name="s3-example-photos-view-prereq-bucket"></a>

在 [Amazon S3 控制台](https://console.aws.amazon.com/s3/)中，创建一个可存储相册和照片的 Amazon S3 桶。有关使用控制台创建 S3 桶的更多信息，请参阅《Amazon Simple Storage Service 用户指南》**中的[创建桶](https://docs.aws.amazon.com/AmazonS3/latest/userguide/create-bucket.html)。

在创建 S3 存储桶时，请务必执行以下操作：
+ 记下存储桶名称，以便在后续先决条件任务“配置角色权限”中使用它。
+ 选择一个要在其中创建存储桶的 AWS 区域。此区域必须与您将在后续先决条件任务“创建身份池”中用于创建 Amazon Cognito 身份池的区域相同。
+ 请按照《Amazon Simple Storage Service 用户指南》**中的[设置访问网站的权限](https://docs.aws.amazon.com/AmazonS3/latest/userguide/WebsiteAccessPermissionsReqd.html)配置存储桶权限。

### 创建身份池
<a name="s3-example-photos-view-prereq-idpool"></a>

在 [Amazon Cognito 控制台](https://console.aws.amazon.com/cognito/)中，创建 Amazon Cognito 身份池，如“浏览器脚本入门”**主题中[步骤 1：创建一个 Amazon Cognito 身份池](getting-started-browser.md#getting-started-browser-create-identity-pool)所述。

当您创建身份池时，请记下身份池名称以及**未经身份验证的**身份的角色名称。

### 配置角色权限
<a name="s3-example-photos-view-prereq-perms"></a>

要允许查看相册和照片，您必须向刚刚创建的身份池的 IAM 角色添加权限。首先按下面所示创建策略。

1. 打开 [IAM 控制台](https://console.aws.amazon.com/iam/)。

1. 在左侧的导航窗格中，选择 **Policies (策略)**，然后选择 **Create policy (创建策略)** 按钮。

1. 在 **JSON** 选项卡上，输入以下 JSON 定义，但将 *BUCKET\$1NAME* 替换为存储桶的名称。

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

****  

   ```
   {
      "Version":"2012-10-17",		 	 	 
      "Statement": [
         {
            "Effect": "Allow",
            "Action": [
               "s3:ListBucket"
            ],
            "Resource": [
               "arn:aws:s3:::BUCKET_NAME"
            ]
         }
      ]
   }
   ```

------

1. 选择 **Review policy (查看策略)** 按钮，为策略命名并提供描述（如果您需要），然后选择 **Create policy (创建策略)** 按钮。

   请务必记下该名称，以便稍后可以找到它并将它附加到 IAM 角色。

创建策略后，导航回 [IAM 控制台](https://console.aws.amazon.com/iam/)。找到 Amazon Cognito 在上一个先决条件任务“创建身份池”中创建的**未经身份验证**的身份的 IAM 角色。您将使用刚刚创建的策略来向此身份添加权限。

尽管此任务的工作流与“浏览器脚本入门”**主题中[步骤 2：将策略添加到创建的 IAM 角色](getting-started-browser.md#getting-started-browser-iam-role)的工作流基本相同，但需要注意一些区别：
+ 使用您刚刚创建的新策略，而不是 Amazon Polly 的策略。
+ 在 **Attach Permissions (附加权限)** 页面上，要快速查找新策略，请打开 **Filter policies (筛选策略)** 列表并选择 **Customer managed (客户管理的)**。

有关创建 IAM 角色的更多信息，请参阅《IAM 用户指南》**中的[创建向 AWS 服务委派权限的角色](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-service.html)。

### 配置 CORS
<a name="s3-example-photos-view-cors-configuration"></a>

在浏览器脚本可以访问 Amazon S3 桶之前，您必须先按以下所示设置其 [CORS 配置](cors.md#configuring-cors-s3-bucket)。

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

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

```
[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "HEAD",
            "GET"
        ],
        "AllowedOrigins": [
            "*"
        ]
    }
]
```

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

```
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedMethod>HEAD</AllowedMethod>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
</CORSConfiguration>
```

------

### 创建相册和上传照片
<a name="s3-example-photos-view-create-albums"></a>

由于本示例仅允许用户查看已在存储桶中的照片，因此您需要在存储桶中创建一些相册并将照片上传到相册。

**注意**  
在本示例中，照片文件的文件名必须以一个下划线（“\$1”）开头。此字符对于稍后进行筛选很重要。此外，请务必尊重照片所有者的版权。

1. 在 [Amazon S3 控制台](https://console.aws.amazon.com/s3/)中，打开您之前创建的桶。

1. 在**概述**选项卡中，选择**创建文件夹**按钮以创建文件夹。在本示例中，将文件夹命名为“album1”、“album2”和“album3”。

1. 对于 **album1** 和 **album2**，选择相应文件夹，然后将照片上传到其中，如下所示：

   1. 选择**上传**按钮。

   1. 拖动或选择要使用的照片文件，然后选择**下一步**。

   1. 在**管理公共权限**下，选择**为此对象授予公共读取访问权限**。

   1. 选择**上传**按钮（左下角）。

1. 将 **album3** 留空。

## 定义网页
<a name="s3-example-photos-view-html"></a>

照片查看应用程序的 HTML 包含一个 `<div>` 元素，在其中，浏览器脚本将创建查看界面。第一个 `<script>` 元素将开发工具包添加到浏览器脚本。第二个 `<script>` 元素添加保存浏览器脚本代码的外部 JavaScript 文件。

在本示例中，该文件名为 `PhotoViewer.js`，并且位于 HTML 文件所在的同一文件夹中。要查找当前的 SDK\$1VERSION\$1NUMBER，请参阅 [适用于 JavaScript 的 AWS SDK API Reference Guide](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/) 中适用于 SDK for JavaScript 的 API 参考。

```
<!DOCTYPE html>
<html>
  <head>
    <!-- **DO THIS**: -->
    <!--   Replace SDK_VERSION_NUMBER with the current SDK version number -->
    <script src="https://sdk.amazonaws.com/js/aws-sdk-SDK_VERSION_NUMBER.js"></script>
    <script src="./PhotoViewer.js"></script>
    <script>listAlbums();</script>
  </head>
  <body>
    <h1>Photo Album Viewer</h1>
    <div id="viewer" />
  </body>
</html>
```



## 配置 SDK
<a name="s3-example-photos-view-config"></a>

通过调用 `CognitoIdentityCredentials` 方法获取配置开发工具包所需的凭证。您需要提供 Amazon Cognito 身份池 ID。然后创建 `AWS.S3` 服务对象。

```
// **DO THIS**:
//   Replace BUCKET_NAME with the bucket name.
//
var albumBucketName = "BUCKET_NAME";

// **DO THIS**:
//   Replace this block of code with the sample code located at:
//   Cognito -- Manage Identity Pools -- [identity_pool_name] -- Sample Code -- JavaScript
//
// Initialize the Amazon Cognito credentials provider
AWS.config.region = "REGION"; // Region
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
  IdentityPoolId: "IDENTITY_POOL_ID",
});

// Create a new service object
var s3 = new AWS.S3({
  apiVersion: "2006-03-01",
  params: { Bucket: albumBucketName },
});

// A utility function to create HTML.
function getHtml(template) {
  return template.join("\n");
}
```

本示例中代码的其余部分定义了以下函数，用于收集和展示有关存储桶中的相册和照片的信息。
+ `listAlbums`
+ `viewAlbum`

## 列出存储桶中的相册
<a name="s3-example-photos-view-list-albums"></a>

为了列出存储桶中的所有现有相册，应用程序的 `listAlbums` 函数将调用 `listObjects` 服务对象的 `AWS.S3` 方法。该函数使用 `CommonPrefixes` 属性，以使调用仅返回用作相册的对象（即文件夹）。

函数的剩余部分从 Amazon S3 桶获取相册列表，并生成在网页上显示相册列表所需的 HTML。

```
// List the photo albums that exist in the bucket.
function listAlbums() {
  s3.listObjects({ Delimiter: "/" }, function (err, data) {
    if (err) {
      return alert("There was an error listing your albums: " + err.message);
    } else {
      var albums = data.CommonPrefixes.map(function (commonPrefix) {
        var prefix = commonPrefix.Prefix;
        var albumName = decodeURIComponent(prefix.replace("/", ""));
        return getHtml([
          "<li>",
          '<button style="margin:5px;" onclick="viewAlbum(\'' +
            albumName +
            "')\">",
          albumName,
          "</button>",
          "</li>",
        ]);
      });
      var message = albums.length
        ? getHtml(["<p>Click on an album name to view it.</p>"])
        : "<p>You do not have any albums. Please Create album.";
      var htmlTemplate = [
        "<h2>Albums</h2>",
        message,
        "<ul>",
        getHtml(albums),
        "</ul>",
      ];
      document.getElementById("viewer").innerHTML = getHtml(htmlTemplate);
    }
  });
}
```

## 查看相册
<a name="s3-example-photos-view-viewing-album"></a>

为显示 Amazon S3 桶中相册的内容，应用程序的 `viewAlbum` 函数获取相册名称并为该相册创建 Amazon S3 键。然后，函数调用 `listObjects` 服务对象的 `AWS.S3` 方法，以获取相册中所有对象（照片）的列表。

函数的剩余部分获取相册中的对象列表并生成在网页上显示照片所需的 HTML。

```
// Show the photos that exist in an album.
function viewAlbum(albumName) {
  var albumPhotosKey = encodeURIComponent(albumName) + "/";
  s3.listObjects({ Prefix: albumPhotosKey }, function (err, data) {
    if (err) {
      return alert("There was an error viewing your album: " + err.message);
    }
    // 'this' references the AWS.Request instance that represents the response
    var href = this.request.httpRequest.endpoint.href;
    var bucketUrl = href + albumBucketName + "/";

    var photos = data.Contents.map(function (photo) {
      var photoKey = photo.Key;
      var photoUrl = bucketUrl + encodeURIComponent(photoKey);
      return getHtml([
        "<span>",
        "<div>",
        "<br/>",
        '<img style="width:128px;height:128px;" src="' + photoUrl + '"/>',
        "</div>",
        "<div>",
        "<span>",
        photoKey.replace(albumPhotosKey, ""),
        "</span>",
        "</div>",
        "</span>",
      ]);
    });
    var message = photos.length
      ? "<p>The following photos are present.</p>"
      : "<p>There are no photos in this album.</p>";
    var htmlTemplate = [
      "<div>",
      '<button onclick="listAlbums()">',
      "Back To Albums",
      "</button>",
      "</div>",
      "<h2>",
      "Album: " + albumName,
      "</h2>",
      message,
      "<div>",
      getHtml(photos),
      "</div>",
      "<h2>",
      "End of Album: " + albumName,
      "</h2>",
      "<div>",
      '<button onclick="listAlbums()">',
      "Back To Albums",
      "</button>",
      "</div>",
    ];
    document.getElementById("viewer").innerHTML = getHtml(htmlTemplate);
    document
      .getElementsByTagName("img")[0]
      .setAttribute("style", "display:none;");
  });
}
```