帮助我们改进AWS SDK for JavaScript版本 3 (V3) 文档,方法是使用反馈链接,或者在上创建议题或拉取请求GitHub
这些区域有:AWS SDK for JavaScriptV3 API 参考指南详细描述了所有的 API 操作AWS SDK for JavaScript版本 3 (V3)。
本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
从浏览器将照片上传到 Amazon S3
此浏览器脚本代码示例演示:
-
如何创建允许用户在 Amazon S3 存储桶中创建相册并将照片上传到相册中的浏览器应用程序。
场景
在本示例中,一个简单的 HTML 页面提供了基于浏览器的应用程序,该应用程序在 Amazon S3 存储桶中创建相册,您可将照片上传到其中。通过该应用程序,您可以删除所添加的照片和相册。

浏览器脚本将 SDK 用于JavaScript与 Amazon S3 存储桶交互。使用 Amazon S3 客户端类的以下方法来启用相册应用程序:
前提任务
要设置和运行此示例,您必须先完成以下任务:
-
设置项目环境以运行这些节点TypeScript示例,然后安装所需AWS SDK for JavaScript和第三方模块。按照中的说明操作GitHub
. -
在Amazon S3 控制台
,创建 Amazon S3 存储桶,您将使用它将在相册中存储照片。有关在控制台中创建存储桶的更多信息,请参阅创建存储桶中的Amazon Simple Storage Service 用户指南. 确保您已拥有两个Read和写入上的权限对象. 有关设置存储桶权限的更多信息,请参阅。设置访问网站的权限. -
在Amazon Cognito 控制台
中,使用联合身份创建 Amazon Cognito 身份池,其中包含为与 Amazon S3 存储桶位于相同区域中的未验证身份用户启用的访问权限。您需要在代码中包含身份池 ID 以获取浏览器脚本的凭证。有关 Amazon Cognito 身份池的更多信息,请参阅Amazon Cognito 身份池(联合身份)中的Amazon Cognito 开发人员指南. -
在IAM 控制台
,查找 Amazon Cognito 为未验证身份用户创建的 IAM 角色。添加以下策略,授予对 Amazon S3 存储桶的读取和写入权限。有关创建 IAM 角色的更多信息,请参阅创建向AWS服务中的IAM 用户指南. 为 Amazon Cognito 为未验证身份用户创建的 IAM 角色使用此角色策略。
警告 如果对未经身份验证的用户启用访问权限,您将向所有人授予对该存储桶及存储桶中的所有对象的写入访问权限。在本示例中,此安全状况很有用,可使其专注于示例的主要目标。但是,在许多实际情况下,强烈建议提高安全性(如使用经身份验证的用户和对象所有权)。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:DeleteObject", "s3:GetObject", "s3:ListBucket", "s3:PutObject", "s3:PutObjectAcl" ], "Resource": [ "arn:aws:s3:::
BUCKET_NAME
", "arn:aws:s3:::BUCKET_NAME
/*" ] } ] }
配置 CORS
在浏览器脚本可以访问 Amazon S3 存储桶之前,您必须先设置它的CORS 配置如下所示。
在 Amazon S3 中AWSWeb 服务管理控制台,CORS 配置必须是 JSON。
安装所需的 SDK 客户端和软件包
安装以下 SDK 模块:
有关安装 SDK 模块的信息,请参阅安装适用于的开发工具包 JavaScript.
-
客户端-S3
-
证书提供商
-
credential-provider-cognito-身份
安装 Webpack
要使用的 V3AWS SDK for JavaScript在浏览器中,你需要 Webpack 来捆绑 JavaScript 模块和函数。
要安装 Web pack,请在命令行中运行以下命令:
npm install --save-dev webpack
要查看此示例的 package.json 示例,请参阅AWS SDK for JavaScript上的代码示例GitHub
有关安装 Webpack 的信息,请参阅使用 webpack 捆绑应用程序.
定义网页
照片查看应用程序的 HTML 包含<div>
元素,浏览器脚本在其中创建查看/上传界面。
这些区域有:<script>
元素添加<main.js>
文件,其中包含所有必需的JavaScript例如。
生成<main.js>
文件,请参阅运行代码下面的。
此示例导入并使用必需的AWS服务 V3 包客户端、V3 命令,并使用send
方法采用异步/等待模式。您可以使用 V2 命令创建此示例,而是通过进行一些小的更改。有关详细信息,请参阅 使用 V3 命令。
<!DOCTYPE html> <html> <head> <script src="./main.js"></script> <script> function getHtml(template) { return template.join("\n"); } listAlbums(); </script> </head> <body> <h1>My photo albums app</h1> <div id="app"></div> </body> </html>
配置开发工具包
通过调用以获取配置开发工具包所需的凭证。CognitoIdentityCredentials
方法,提供 Amazon Cognito 身份池 ID。接下来,创建一个S3
客户端服务对象。
此示例导入并使用必需的AWS服务 V3 包客户端、V3 命令,并使用send
方法采用异步/等待模式。您可以使用 V2 命令创建此示例,而是通过进行一些小的更改。有关详细信息,请参阅 使用 V3 命令。
// Load the required clients and packages const { CognitoIdentityClient } = require("@aws-sdk/client-cognito-identity"); const { fromCognitoIdentityPool, } = require("@aws-sdk/credential-provider-cognito-identity"); const { S3Client, PutObjectCommand, ListObjectsCommand, DeleteObjectCommand, DeleteObjectsCommand } = require("@aws-sdk/client-s3"); // Set the AWS Region const REGION = "REGION"; //REGION // Initialize the Amazon Cognito credentials provider const s3 = new S3Client({ region: REGION, credentials: fromCognitoIdentityPool({ client: new CognitoIdentityClient({ region: REGION }), identityPoolId: "IDENTITY_POOL_ID", // IDENTITY_POOL_ID }), }); const albumBucketName = "BUCKET_NAME"; //BUCKET_NAME
此示例中几乎所有剩余的代码组织成一系列函数,这些函数收集并提供存储桶中相册的相关信息,上传并显示上传到相册中的照片,以及删除照片和相册。这些函数包括:
-
listAlbums
-
createAlbum
-
viewAlbum
-
addPhoto
-
deleteAlbum
-
deletePhoto
在存储桶中列出相册
应用程序在 Amazon S3 存储桶中将相册创建为对象,其键以正斜杠字符开头,指示该对象用作文件夹。为列出存储桶中的所有现有相册,应用程序的listAlbums
函数调用ListObjectsCommand
的方法S3
使用时的客户端服务对象commonPrefix
所以调用只返回用作相册的对象。
函数的剩余部分从 Amazon S3 存储桶获取相册列表,并生成在网页中显示相册列表所需的 HTML。它还支持删除和打开单独的相册。
此示例导入并使用必需的AWS服务 V3 包客户端、V3 命令,并使用send
方法采用异步/等待模式。您可以使用 V2 命令创建此示例,而是通过进行一些小的更改。有关详细信息,请参阅 使用 V3 命令。
// A utility function to create HTML function getHtml(template) { return template.join("\n"); } // Make getHTML function available to the browser window.getHTML = getHtml; // List the photo albums that exist in the bucket const listAlbums = async () => { try { const data = await s3.send( new ListObjectsCommand({ Delimiter: "/", Bucket: albumBucketName }) ); if (data.CommonPrefixes === undefined) { const htmlTemplate = [ "<p>You don't have any albums. You need to create an album.</p>", "<button onclick=\"createAlbum(prompt('Enter album name:'))\">", "Create new album", "</button>", ]; document.getElementById("app").innerHTML = htmlTemplate; } else { var albums = data.CommonPrefixes.map(function (commonPrefix) { var prefix = commonPrefix.Prefix; var albumName = decodeURIComponent(prefix.replace("/", "")); return getHtml([ "<li>", "<span onclick=\"deleteAlbum('" + albumName + "')\">X</span>", "<span onclick=\"viewAlbum('" + albumName + "')\">", albumName, "</span>", "</li>", ]); }); var message = albums.length ? getHtml([ "<p>Click an album name to view it.</p>", "<p>Click the X to delete the album.</p>", ]) : "<p>You do not have any albums. You need to create an album."; const htmlTemplate = [ "<h2>Albums</h2>", message, "<ul>", getHtml(albums), "</ul>", "<button onclick=\"createAlbum(prompt('Enter Album Name:'))\">", "Create new Album", "</button>", ]; document.getElementById("app").innerHTML = getHtml(htmlTemplate); } } catch (err) { return alert("There was an error listing your albums: " + err.message); } }; // Make listAlbums function available to the browser window.listAlbums = listAlbums;
在存储桶中创建相册
为在 Amazon S3 存储桶中创建相册,应用程序的createAlbum
函数首先验证为新相册提供的名称,确保它包含合适的字符。然后,函数构成 Amazon S3 对象键,将其传递到headObject
Amazon S3 服务对象的方法。此方法返回指定键的元数据,因此如果它返回数据,则具有该键的对象已存在。
如果相册尚不存在,则函数调用PutObjectCommand
的方法S3
用于创建相册的客户端服务对象。然后,它调用 viewAlbum
函数以显示新的空相册。
此示例导入并使用必需的AWS服务 V3 包客户端、V3 命令,并使用send
方法采用异步/等待模式。您可以使用 V2 命令创建此示例,而是通过进行一些小的更改。有关详细信息,请参阅 使用 V3 命令。
// Create an album in the bucket const createAlbum = async (albumName) => { albumName = albumName.trim(); if (!albumName) { return alert("Album names must contain at least one non-space character."); } if (albumName.indexOf("/") !== -1) { return alert("Album names cannot contain slashes."); } var albumKey = encodeURIComponent(albumName); try { const key = albumKey + "/"; const params = { Bucket: albumBucketName, Key: key }; const data = await s3.send(new PutObjectCommand(params)); alert("Successfully created album."); viewAlbum(albumName); } catch (err) { return alert("There was an error creating your album: " + err.message); } }; // Make createAlbum function available to the browser window.createAlbum = createAlbum;
查看相册
为显示 Amazon S3 存储桶中相册的内容,应用程序的viewAlbum
函数获取相册名称并为该相册创建 Amazon S3 密钥。然后该函数调用listObjects
的方法S3
客户端服务对象,获取相册中所有对象(照片)的列表。
函数的剩余部分从相册获取对象(照片)列表并生成在网页中显示照片所需的 HTML。它还支持删除单独的照片以及导航回相册列表。
// View the contents of an album const viewAlbum = async (albumName) => { const albumPhotosKey = encodeURIComponent(albumName) + "/"; try { const data = await s3.send( new ListObjectsCommand({ Prefix: albumPhotosKey, Bucket: albumBucketName, }) ); if (data.Contents.length === 1) { var htmlTemplate = [ "<p>You don't have any photos in this album. You need to add photos.</p>", '<input id="photoupload" type="file" accept="image/*">', '<button id="addphoto" onclick="addPhoto(\'' + albumName + "')\">", "Add photo", "</button>", '<button onclick="listAlbums()">', "Back to albums", "</button>", ]; document.getElementById("app").innerHTML = getHtml(htmlTemplate); } else { console.log(data); const href = "https://s3." + REGION + ".amazonaws.com/"; const bucketUrl = href + albumBucketName + "/"; const photos = data.Contents.map(function (photo) { const photoKey = photo.Key; console.log(photo.Key); const photoUrl = bucketUrl + encodeURIComponent(photoKey); return getHtml([ "<span>", "<div>", '<img style="width:128px;height:128px;" src="' + photoUrl + '"/>', "</div>", "<div>", "<span onclick=\"deletePhoto('" + albumName + "','" + photoKey + "')\">", "X", "</span>", "<span>", photoKey.replace(albumPhotosKey, ""), "</span>", "</div>", "</span>", ]); }); var message = photos.length ? "<p>Click the X to delete the photo.</p>" : "<p>You don't have any photos in this album. You need to add photos.</p>"; const htmlTemplate = [ "<h2>", "Album: " + albumName, "</h2>", message, "<div>", getHtml(photos), "</div>", '<input id="photoupload" type="file" accept="image/*">', '<button id="addphoto" onclick="addPhoto(\'' + albumName + "')\">", "Add photo", "</button>", '<button onclick="listAlbums()">', "Back to albums", "</button>", ]; document.getElementById("app").innerHTML = getHtml(htmlTemplate); document.getElementsByTagName("img")[0].remove(); } } catch (err) { return alert("There was an error viewing your album: " + err.message); } }; // Make viewAlbum function available to the browser window.viewAlbum = viewAlbum;
将照片添加到相册
为将照片上传到 Amazon S3 存储桶中的相册,应用程序的addPhoto
函数在网页中使用文件选取器元素来标识要上传的文件。然后,它从当前相册名称和文件名,为上传的照片构成一个键。
函数调用putObject
用于上传照片的 Amazon S3 服务对象的方法。上传照片后,函数将重新显示相册,这样上传的照片会显示。
// Add a photo to an album const addPhoto = async (albumName) => { const files = document.getElementById("photoupload").files; try { const albumPhotosKey = encodeURIComponent(albumName) + "/"; const data = await s3.send( new ListObjectsCommand({ Prefix: albumPhotosKey, Bucket: albumBucketName }) ); const file = files[0]; const fileName = file.name; const photoKey = albumPhotosKey + fileName; const uploadParams = { Bucket: albumBucketName, Key: photoKey, Body: file }; try { const data = await s3.send(new PutObjectCommand(uploadParams)); alert("Successfully uploaded photo."); viewAlbum(albumName); } catch (err) { return alert("There was an error uploading your photo: ", err.message); } } catch (err) { if (!files.length) { return alert("Choose a file to upload first."); } } }; // Make addPhoto function available to the browser window.addPhoto = addPhoto;
删除照片
为从 Amazon S3 存储桶中删除相册中的照片,应用程序的deletePhoto
函数调用DeleteObjectCommand
Amazon S3 客户端服务对象的方法。这会删除传递到函数的 photoKey
值指定的照片。
// Delete a photo from an album const deletePhoto = async (albumName, photoKey) => { try { console.log(photoKey); const params = { Key: photoKey, Bucket: albumBucketName }; const data = await s3.send(new DeleteObjectCommand(params)); console.log("Successfully deleted photo."); viewAlbum(albumName); } catch (err) { return alert("There was an error deleting your photo: ", err.message); } }; // Make deletePhoto function available to the browser window.deletePhoto = deletePhoto;
删除相册
为从 Amazon S3 存储桶中删除相册,应用程序的deleteAlbum
函数调用deleteObjects
Amazon S3 客户端服务对象的方法。
// Delete an album from the bucket const deleteAlbum = async (albumName) => { const albumKey = encodeURIComponent(albumName) + "/"; try { const params = { Bucket: albumBucketName, Prefix: albumKey }; const data = await s3.send(new ListObjectsCommand(params)); const objects = data.Contents.map(function (object) { return { Key: object.Key }; }); try { const params = { Bucket: albumBucketName, Delete: { Objects: objects }, Quiet: true, }; const data = await s3.send(new DeleteObjectsCommand(params)); listAlbums(); return alert("Successfully deleted album."); } catch (err) { return alert("There was an error deleting your album: ", err.message); } } catch (err) { return alert("There was an error deleting your album1: ", err.message); } }; // Make deleteAlbum function available to the browser window.deleteAlbum = deleteAlbum;
运行代码
为此示例运行代码
-
将所有代码保存为
s3_PhotoExample.js
.注意 此文件可用此处GitHub
. -
Replace
“地区”
和你的AWS区域,例如 “us-east-1”。 -
Replace
“BUCKET_NAME”
与 Amazon S3 存储桶一起使用。 -
Replace
“身份 _POOL_ID”
使用IdentityPool我来自示例页面为本示例创建的 Amazon Cognito 身份池。注意 这些区域有:
IDENTITY_POOL_ID
在控制台中显示为红色。 -
在命令行中运行以下命令以捆绑JavaScript对于此示例,请参阅一个名为的文件
<main.js>
:npx webpack ./src/s3_PhotoExample.js --mode development --target web --no-devtool -o main.js
注意 有关安装的信息WebPack,请参阅使用 webpack 捆绑应用程序.
在命令行中运行以下命令:
node s3_PhotoExample.js