Après avoir sélectionné un fichier image sur le site Web, je voulais POSTER l'image avec des données en plusieurs parties / formulaire avec le bouton de téléchargement et l'enregistrer dans S3 sur AWS, j'ai donc compris comment le faire. Cela peut être utile si vous souhaitez utiliser les services AWS, y compris l'enregistrement d'images sur votre site Web.
Nous utilisons ** HTML, CSS, JavaScript ** comme langage de développement côté Web et ** Python 3.7 ** comme langage côté Lambda. Voici les services utilisés.
** ・ AWS Lambda ** Un service AWS qui vous permet d'exécuter un code de fonction déclenché par un événement. ** - Amazon S3 (utilisé pour enregistrer les images téléchargées et comme lieu de publication de sites Web) ** Abréviation de Simple Storage Service, service de stockage en ligne AWS
Après avoir POSTÉ l'image sous la forme de multipart / form-data sur le côté Web à l'aide d'ajax, démarrez Lambda en appuyant sur API Gateway et enregistrez l'image dans S3 avec la fonction dans Lambda. En prime, stockez le nom de fichier de l'image enregistrée dans le stockage local du site afin de pouvoir parcourir l'image enregistrée.
Cela devient la procédure.
Cette fois, j'ai pris la forme de POST à l'API sous la forme de multipart / form-data du côté du site Web. Nous effectuons également un traitement pour empêcher la transition vers un autre écran lorsque vous cliquez sur le bouton Soumettre et modifions le style de divers boutons.
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!--la bibliothèque jquery n'est pas corrigée-->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<title>Title</title>
<style>
label > input {
display:none; /*Désactiver le style du bouton de fichier*/
}
label > button {
display:none; /*Désactiver le style de bouton*/
}
label {
display: inline-block;
padding: 0.5em 1em;
text-decoration: none;
background: #fd9535;/*Couleur du bouton*/
color: #FFF;
border-bottom: solid 4px #627295;
border-radius: 3px;
}
button{
display: inline-block;
padding: 0.5em 1em;
text-decoration: none;
background: #fd9535;/*Couleur du bouton*/
color: #FFF;
border-bottom: solid 4px #627295;
border-radius: 3px;
}
label:active {
/*Lorsque vous appuyez sur le bouton*/
-webkit-transform: translateY(4px);
transform: translateY(4px);/*Descendre*/
border-bottom: none;/*Effacer la ligne*/
}
button:active{
/*Lorsque vous appuyez sur le bouton*/
-webkit-transform: translateY(4px);
transform: translateY(4px);/*Descendre*/
border-bottom: none;/*Effacer la ligne*/
}
</style>
</head>
<body>
<form action="xxx Où saisir l'URL de la passerelle API xxx" method="post" enctype="multipart/form-data" id="imgForm" target="sendPhoto">
<p>
<label for ="upfile">
Veuillez sélectionner un fichier
<input type="file" name="fileName" id="upfile" accept="image/*" capture="camera">
</label>
<span style="color: #ff0000;" data-mce-style="color: #ff0000;"><div><img id="thumbnail" src=""></div></span>
</p>
<p>
<label for="upload">
télécharger
<button type="submit" action="" name="save" id="upload" >upload</button>
</label>
</p>
<p id="compUpload"></p>
</form>
<iframe name="sendPhoto" style="width:0px;height:0px;border:0px;"></iframe>
<script>
$('#upfile').change(function(){
if (this.files.length > 0) {
//Obtenir les informations sur le fichier sélectionné
var file = this.files[0];
//Stocker les données de fichier codées en tant qu'URL de données dans la propriété result du lecteur
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function() {
$('#thumbnail').attr('src', reader.result );
}
}
});
//Télécharger l'image
$('#imgForm').on('submit', function(e) {
e.preventDefault();
var formData = new FormData($('#imgForm').get(0));
$.ajax($(this).attr('action'), {
type: 'post',
processData: false,
contentType: false,
data: formData,
success: document.getElementById('compUpload').innerHTML = 'Téléchargement' //Lorsque la transmission est réussie
}).done(function(response){
let jsonbody = JSON.parse(response.body);
console.log('succes!'); //Quand il y a une réponse
//Stocker le nom du fichier de réponses dans le stockage local
var array = [];
var obj = {
'Clé 1': 'Valeur 1',
'Clé 2': 'Valeur 2'
};
array.push(obj);
var setjson = JSON.stringify(obj);
localStorage.setItem('Clé', jsonbody.message);
document.getElementById('compUpload').innerHTML = 'Téléchargement terminé'
}).fail(function() {
console.log('error!'); //Lorsqu'une erreur survient
});
return false;
});
</script>
</body>
</html>
Copiez et collez le code ci-dessus pour créer un fichier html. Placez le fichier sur votre serveur préféré ou S3 et affichez-le. Ceci termine la création côté Web à l'exception de "Spécifier l'URL de la passerelle API".
Le code ci-dessous est la partie spécifiée
python
<body>
<form action="xxx Où saisir l'URL de la passerelle API xxx" method="post" enctype="multipart/form-data" id="imgForm" target="sendPhoto">
Nous ajouterons ceci lorsque nous connaîtrons l'URL de la passerelle API dans les étapes ultérieures de création de Lambda. De plus, le bouton par défaut était terne, j'ai donc changé la conception avec la balise de style en haut du code. L'affichage par défaut est masqué avec display: none; puis changé pour un nouveau design.
python
<style>
label > input {
display:none; /*Désactiver le style du bouton de fichier*/
}
label > button {
display:none; /*Désactiver le style de bouton*/
}
label {
display: inline-block;
padding: 0.5em 1em;
text-decoration: none;
background: #fd9535;/*Couleur du bouton*/
color: #FFF;
border-bottom: solid 4px #627295;
border-radius: 3px;
}
button{
display: inline-block;
padding: 0.5em 1em;
text-decoration: none;
background: #fd9535;/*Couleur du bouton*/
color: #FFF;
border-bottom: solid 4px #627295;
border-radius: 3px;
}
label:active {
/*Lorsque vous appuyez sur le bouton*/
-webkit-transform: translateY(4px);
transform: translateY(4px);/*Descendre*/
border-bottom: none;/*Effacer la ligne*/
}
button:active{
/*Lorsque vous appuyez sur le bouton*/
-webkit-transform: translateY(4px);
transform: translateY(4px);/*Descendre*/
border-bottom: none;/*Effacer la ligne*/
}
</style>
J'utilise ajax pour télécharger des images. Si le POST côté serveur réussit, le côté Web indiquera que le téléchargement est en cours.
python
<script>
//Télécharger l'image
$('#imgForm').on('submit', function(e) {
e.preventDefault();
var formData = new FormData($('#imgForm').get(0));
$.ajax($(this).attr('action'), {
type: 'post',
processData: false,
contentType: false,
data: formData,
success: document.getElementById('compUpload').innerHTML = 'Téléchargement' //Lorsque la transmission est réussie
}).done(function(response){
let jsonbody = JSON.parse(response.body);
console.log('succes!'); //Quand il y a une réponse
//Stocker le nom du fichier de réponses dans le stockage local
var array = [];
var obj = {
'Clé 1': 'Valeur 1',
'Clé 2': 'Valeur 2'
};
array.push(obj);
var setjson = JSON.stringify(obj);
localStorage.setItem('Clé', jsonbody.message);
document.getElementById('compUpload').innerHTML = 'Téléchargement terminé'
}).fail(function() {
console.log('error!'); //Lorsqu'une erreur survient
});
return false;
});
</script>
Utilisez S3 comme emplacement pour télécharger des fichiers image à partir du Web. Sélectionnez S3 dans AWS Management Console et créez un compartiment. Il est recommandé que la région spécifiée à ce stade soit la même que la région spécifiée lors de la création de Lambda ultérieurement. (Parce que cela peut prendre du temps pour refléter les paramètres d'une autre région) ⇨ Lien de référence Il n'y a pas de problème avec les paramètres au moment de la création par défaut, mais dans cet article, dans les paramètres d'autorisation d'accès, décochez "Bloquer tous les accès publics" et définissez pour autoriser l'accès public. (Pour afficher la réponse dans Lambda sur le Web) Si vous souhaitez définir l'autorisation d'accès individuellement, définissez-la à partir de la stratégie de compartiment après la création.
Si vous spécifiez le chemin du compartiment créé ici plus tard dans Lambda, l'image téléchargée sera supprimée.
Lambda exécute une fonction qui enregistre une image dans S3, déclenchée par un POST d'image côté Web. Pour ce faire, sélectionnez d'abord Lambda dans AWS Management Console et cliquez sur Créer une fonction. Au moment de sa création, cet article a été créé dans la région du nord de la Virginie. (Recommandé pour être identique à la région créée dans S3)
Sur l'écran de création de fonction, ・ Créer à partir de zéro -Nom de la fonction (entrez le nom de votre fonction préférée) ・ Runtime (en utilisant Python 3.7 cette fois) · Rôle d'exécution (choisissez créer un nouveau rôle avec un accès Lambda de base)
Après avoir décidé ces derniers, cliquez sur Créer une fonction. Ici, le nom de la fonction est myFunctionName. Le rôle Exécuter accorde l'accès à S3 et à Cloud Watch, mais créez-le d'abord avec les autorisations Lambda de base et ajoutez-le ultérieurement.
Lorsque la création de la fonction est terminée, l'écran d'édition de la fonction s'ouvre. Cliquez sur ** Ajouter un déclencheur ** dans la fenêtre Designer. La fenêtre changera, alors sélectionnez ** API Gateway ** et définissez les paramètres détaillés.
Sur l'écran Ajouter un déclencheur, avec la liste déroulante et les choix de boutons radio respectifs ・ API ⇨ Créer une nouvelle API -Sélectionnez un modèle ⇨ API REST ・ Sécurité ⇨ Ouvrir ・ Cliquez sur les paramètres supplémentaires ⇨ Ajout de ** image / png ** et ** multipart / form-data ** aux types de supports binaires Après cela, cliquez sur ** Ajouter ** en bas à droite de l'écran.
Ensuite, vous devriez voir API Gateway ajouté à Designer comme indiqué dans l'image ci-dessous. Il s'agit d'un mécanisme dans lequel API Gateway reçoit un POST côté Web et déclenche le démarrage de la fonction Lambda.
Lorsque vous cliquez sur API Gateway dans Designer, vous verrez un ** point de terminaison API ** commençant par https. Entrez cette URL comme [Partie incertaine de la procédure de création d'un site Web](# Le code ci-dessous est -url-). Entrez dans (partie).
Ensuite, cliquez sur le lien "Nom de la fonction-API" affiché directement au-dessus du point de terminaison de l'API pour créer une méthode API.
Cliquez sur le lien "Nom de la fonction-API" pour ouvrir la page des paramètres API Gateway. Configurez maintenant la méthode API POST pour recevoir les fichiers au format json de votre site Web.
Cliquez sur ** Créer une méthode ** dans l'action pour afficher la boîte de sélection (cliquez sur la flèche de pliage à droite du nom de la fonction)
Sélectionnez ** POST ** dans la case de sélection et cliquez sur la coche
Sélectionnez POST, sélectionnez la région Lambda que vous utilisez sur l'écran qui s'affiche, puis entrez le nom de la fonction que vous avez créée précédemment dans le champ de saisie ** Fonction Lambda ** et cliquez sur Enregistrer.
Cliquez sur OK si une fenêtre pour ajouter des autorisations à la fonction Lambda apparaît
Sélectionnez Activer CORS à partir des actions, entrez "vrai" dans Advanced Access-Control-Allow-Credentials (y compris ""), activez CORS et cliquez sur Remplacer l'en-tête CORS existant par la valeur Ajouter.
Sélectionnez à nouveau ** POST **, cliquez sur ** Demande d'intégration ** sur l'écran d'exécution de la méthode, et modèle de mappage ⇨ si aucun modèle n'est défini (recommandé) ⇨ ajouter un modèle de mappage ⇨ ** multipart / Entrez les données du formulaire ** ⇨ Sélectionnez ** Méthode demande passthrough ** dans Générer le modèle et enregistrez
Après avoir cliqué sur le bouton Enregistrer, sélectionnez ** Nom de la fonction ** au-dessus de TOUT, sélectionnez Déployer l'API à partir des actions, sélectionnez par défaut pour l'étape à déployer, puis cliquez sur le bouton Déployer.
Ceci termine les paramètres de l'API. Veuillez noter qu'il y a plusieurs étapes et qu'il est facile de faire des erreurs. Ensuite, nous allons passer aux paramètres du code de fonction, donc revenez à l'écran des paramètres de la fonction Lambda. Vous pouvez retourner par service ⇨ Lambda ⇨ nom de la fonction.
①
②
③
④
⑤
⑥
⑦
Si vous cliquez sur le nom de la fonction dans Designer et faites défiler, il y a un élément pour écrire le code de la fonction, alors écrivez le code en Python ici. Ici, le décodage de l'image, le réglage de l'emplacement de stockage, la réponse pour acquérir le nom de l'image côté Web, etc. sont décrits.
lambda_function.py
import json
import boto3
import base64
from datetime import datetime, timezone
def convert_b64_string_to_bynary(s):
"""Décoder base64"""
def lambda_handler(event, context):
#Paramètre de l'emplacement de stockage des images
s3 = boto3.resource('s3')
bucket = s3.Bucket('xxx Nom du seau pour stocker les images xxx')
#Le binaire est encodé en Base64, donc décodez ici
imageBody = base64.b64decode(event['body-json'])
TextTime = datetime.now().strftime('%Y-%m-%d-%H-%M-%S') #Définissez le nom du fichier image téléchargé sur l'heure à ce moment
images = imageBody.split(b'\r\n',4)#Coupez uniquement la partie nécessaire avec fractionnement
key = TextTime +".png "
bucket.put_object(
Body = images[4],
Key = key
)
#Valeur de retour pour obtenir le nom de l'image côté Web
return {
'isBase64Encoded': False,
'statusCode': 200,
'headers': {'Access-Control-Allow-Origin' : '*' ,
'Content-Type' :'application/json'},
'body': '{"message":"'+ key + '"}'
}
Après avoir collé le code, entrez le nom du compartiment S3 dans la partie suivante et enregistrez l'état avec le bouton Enregistrer en haut à droite de l'écran.
lambda_function.py
bucket = s3.Bucket('xxx Nom du seau pour stocker les images xxx')
Définissez des variables d'environnement pour ajuster l'horodatage à l'heure japonaise. Si vous faites défiler un peu vers le bas depuis l'écran du code de fonction, vous trouverez un élément pour les variables d'environnement. Suivez les étapes ci-dessous pour définir les variables d'environnement.
Si vous faites défiler un peu vers le bas à partir de l'élément de variable d'environnement, vous trouverez l'élément de paramètre de rôle d'exécution. Suivez les étapes ci-dessous pour définir le rôle d'exécution.
Ceci termine tous les paramètres. Essayez de télécharger l'image à partir de l'écran Web et cela réussit si l'image est enregistrée dans le compartiment correspondant de S3. En prime, vous pouvez également vérifier que le nom du fichier est enregistré dans le stockage local au moment du téléchargement avec l'outil de développement. Veuillez l'utiliser lorsque vous utilisez un service qui spécifie le fichier téléchargé.
Cette fois, j'avais l'habitude de faire référence aux images S3 avec un service appelé Amazon Rekognition Custom Labels sur AWS, j'ai donc implémenté une telle fonction. Si vous êtes intéressé, veuillez consulter l'article ci-dessous pour la convivialité. À propos de la convivialité des étiquettes personnalisées Amazon Rekognition
Pourquoi Amazon S3 renvoie-t-il une réponse de redirection temporaire HTTP 307? Comment empêcher la transition d'écran lors du traitement POST avec Form
Recommended Posts