Anunciamos
Carga de fotos en Amazon S3 desde un navegador
Este ejemplo de código de script de navegador muestra:
-
Cómo crear una aplicación de navegador que permita a los usuarios crear álbumes de fotos en un bucket de Amazon S3 y cargar fotos en los álbumes.
El escenario
En este ejemplo, una página HTML sencilla proporciona una aplicación basada en navegador para crear álbumes de fotos en un bucket de Amazon S3 en el que puede cargar fotos. La aplicación le permite eliminar fotos y álbumes que añade.
![JavaScript en un script de navegador que usa buckets de Amazon S3 para álbumes de fotos.](images/s3-photo-album-example.png)
El script de navegador usa el SDK para JavaScript para interactuar con un bucket de Amazon S3. Utilice los siguientes métodos de la clase de cliente de Amazon S3 para habilitar la aplicación de álbum de fotos:
Tareas previas necesarias
Para configurar y ejecutar este ejemplo, primero debe completar estas tareas:
-
En la consola de Amazon S3
cree un bucket de Amazon S3 que utilizará para almacenar las fotos en el álbum. Para obtener más información acerca de la creación de un bucket, consulte la sección de creación de un bucket en la Guía del usuario de Amazon Simple Storage Service. Asegúrese de que tiene permisos de lectura y escritura en Objects (Objetos). Para obtener más información acerca de los permisos en buckets, consulte Configurar permisos para el acceso a sitios web. -
En la consola de Amazon Cognito
cree un grupo de identidades de Amazon Cognito usando identidades federadas con acceso habilitado para usuarios no autenticados en la misma región que el bucket de Amazon S3. Debe incluir el ID del grupo de identidades en el código para obtener las credenciales para el script del navegador. Para obtener más información sobre las identidades federadas de Amazon Cognito, consulte Grupos de identidades de Amazon Cognito (identidades federadas) en la Guía para desarrolladores de Amazon Cognito. -
En la consola de IAM
busque el rol de IAM creado por Amazon Cognito para los usuarios sin autenticar. Añada la política siguiente para conceder permisos de lectura y escritura a un bucket de Amazon S3. Para obtener más información sobre cómo crear un rol de IAM, consulte Creación de un rol para delegar permisos a un servicio de AWS en la Guía del usuario de IAM. Utilice esta política de roles para el rol de IAM creado por Amazon Cognito para usuarios sin autenticar.
aviso
Si habilita el acceso a usuarios sin autenticar, concederá acceso de escritura al bucket y a todos los objetos del bucket a todas las personas del mundo. Este enfoque de seguridad es útil en este ejemplo para centrarnos en los principales objetivos del ejemplo. Sin embargo, en muchas situaciones de la vida real, es muy recomendable aplicar una seguridad más estricta, como usuarios autenticados y titularidad de los objetos.
{ "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
/*" ] } ] }
Configuración de CORS
Para que el script de navegador pueda obtener acceso al bucket de Amazon S3, primero tiene que configurar su configuración de CORS tal y como se indica a continuación.
importante
En la nueva consola S3, la configuración de CORS debe ser JSON.
La página web
El HTML para la aplicación de carga de fotos consta de un elemento <div> en el que el script de navegador crea la interfaz de usuario de carga. El primer elemento <script> añade el SDK al script de navegador. El segundo elemento <script> añade el archivo JavaScript externo que contiene el código de script de navegador.
<!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="./s3_photoExample.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>
Configuración del SDK
Obtenga las credenciales necesarias para configurar el SDK llamando al método CognitoIdentityCredentials
, indicando el ID de grupo de identidades de Amazon Cognito. A continuación cree un objeto de servicio AWS.S3
.
var albumBucketName = "BUCKET_NAME"; var bucketRegion = "REGION"; var IdentityPoolId = "IDENTITY_POOL_ID"; AWS.config.update({ region: bucketRegion, credentials: new AWS.CognitoIdentityCredentials({ IdentityPoolId: IdentityPoolId, }), }); var s3 = new AWS.S3({ apiVersion: "2006-03-01", params: { Bucket: albumBucketName }, });
Prácticamente el resto del código de este ejemplo está organizado en una serie de funciones que reúnen y presentan información sobre los álbumes en el bucket, cargan y muestran fotos cargadas en álbumes, y eliminan fotos y álbumes. Dichas funciones son las siguientes:
-
listAlbums
-
createAlbum
-
viewAlbum
-
addPhoto
-
deleteAlbum
-
deletePhoto
Listas de álbumes en el bucket
La aplicación crea álbumes en el bucket de Amazon S3 como objetos cuyas claves comienzan con una barra inclinada para indicar que el objeto funciona como una carpeta. Para obtener una lista de todos los álbumes existentes en el bucket, la función listAlbums
de la aplicación llama al método listObjects
del objeto de servicio AWS.S3
al utilizar commonPrefix
por lo que la llamada devuelve solo objetos que se utilizan como álbumes.
El resto de la función toma la lista de álbumes del bucket de Amazon S3 y genera el código HTML necesario para mostrar la lista de álbumes en la página web. También habilitar la eliminación y apertura de álbumes individuales.
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>", "<span onclick=\"deleteAlbum('" + albumName + "')\">X</span>", "<span onclick=\"viewAlbum('" + albumName + "')\">", albumName, "</span>", "</li>", ]); }); var message = albums.length ? getHtml([ "<p>Click on an album name to view it.</p>", "<p>Click on the X to delete the album.</p>", ]) : "<p>You do not have any albums. Please Create album."; var 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); } }); }
Creación de un álbum en el bucket
Para crear un álbum en el bucket de Amazon S3, la función createAlbum
de la aplicación primero valida el nombre que se da al nuevo álbum para asegurarse de que los caracteres que contiene son adecuados. A continuación, la función crea una clave de objeto de Amazon S3 y la pasa al método headObject
del objeto de servicio de Amazon S3. Este método devuelve los metadatos de la clave especificada, por lo que si se devuelven datos significa que ya existe un objeto con dicha clave.
Si el álbum no existe todavía, la función llama al método putObject
del objeto de servicio AWS.S3
para crear el álbum. A continuación llama a la función viewAlbum
para mostrar el nuevo álbum vacío.
function createAlbum(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); s3.headObject({ Key: albumKey }, function (err, data) { if (!err) { return alert("Album already exists."); } if (err.code !== "NotFound") { return alert("There was an error creating your album: " + err.message); } s3.putObject({ Key: albumKey }, function (err, data) { if (err) { return alert("There was an error creating your album: " + err.message); } alert("Successfully created album."); viewAlbum(albumName); }); }); }
Visualización de un álbum
Para mostrar el contenido de un álbum en el bucket de Amazon S3, la función viewAlbum
de la aplicación toma un nombre de álbum y crea la clave de Amazon S3 para dicho álbum. Luego la función llama al método listObjects
del objeto de servicio AWS.S3
para obtener una lista de todos los objetos (fotos) del álbum.
El resto de la función toma la lista de objetos (fotos) del álbum y genera el código HTML necesario para mostrar las fotos en la página web. También permite eliminar fotos individuales y volver a la lista de álbumes.
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.Response 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>", '<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 on the X to delete the photo</p>" : "<p>You do not have any photos in this album. Please add photos.</p>"; var 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); }); }
Añadir fotos a un álbum
Para cargar una foto a un álbum en el bucket de Amazon S3, la función addPhoto
de la aplicación utiliza un elemento selector de archivos en la página web para identificar un archivo para cargarlo. A continuación forma una clave para la foto que se va a cargar a partir del nombre del álbum actual y el nombre del archivo.
La función llama al método upload
del objeto de servicio de Amazon S3 para cargar la foto. Después de cargar la foto, la función vuelve a mostrar el álbum de modo que la foto cargada aparezca.
function addPhoto(albumName) { var files = document.getElementById("photoupload").files; if (!files.length) { return alert("Please choose a file to upload first."); } var file = files[0]; var fileName = file.name; var albumPhotosKey = encodeURIComponent(albumName) + "/"; var photoKey = albumPhotosKey + fileName; // Use S3 ManagedUpload class as it supports multipart uploads var upload = new AWS.S3.ManagedUpload({ params: { Bucket: albumBucketName, Key: photoKey, Body: file, }, }); var promise = upload.promise(); promise.then( function (data) { alert("Successfully uploaded photo."); viewAlbum(albumName); }, function (err) { return alert("There was an error uploading your photo: ", err.message); } ); }
Eliminación de una foto
Para eliminar una foto de un álbum en el bucket de Amazon S3, la función deletePhoto
de la aplicación llama al método deleteObject
del objeto de servicio de Amazon S3. Esto elimina la foto que se ha especificado con el valor photoKey
que se ha transferido a la función.
function deletePhoto(albumName, photoKey) { s3.deleteObject({ Key: photoKey }, function (err, data) { if (err) { return alert("There was an error deleting your photo: ", err.message); } alert("Successfully deleted photo."); viewAlbum(albumName); }); }
Eliminación de un álbum
Para eliminar un álbum en el bucket de Amazon S3, la función deleteAlbum
de la aplicación llama al método deleteObjects
del objeto de servicio de Amazon S3.
function deleteAlbum(albumName) { var albumKey = encodeURIComponent(albumName) + "/"; s3.listObjects({ Prefix: albumKey }, function (err, data) { if (err) { return alert("There was an error deleting your album: ", err.message); } var objects = data.Contents.map(function (object) { return { Key: object.Key }; }); s3.deleteObjects( { Delete: { Objects: objects, Quiet: true }, }, function (err, data) { if (err) { return alert("There was an error deleting your album: ", err.message); } alert("Successfully deleted album."); listAlbums(); } ); }); }