使用 Learner Lab - 使用 S3 静态网页上传图片,搭配 API Gateway 与 Lambda

news2024/10/5 13:53:42

使用 Learner Lab - 使用 S3 静态网页上传图片,搭配 API Gateway 与 Lambda

AWS Academy Learner Lab 是提供一个帐号让学生可以自行使用 AWS 的服务,让学生可以在 100 USD的金额下,自行练习所要使用的 AWS 服务,如何进入 Learner Lab 请参考 使用 Learner Lab - 学生,而这篇文章是使用 S3 静态网页上传图片,搭配 API Gateway 与 Lambda,完整的介绍前后端的交互。

下图中的 1.号路线就是 使用 Learner Lab - 使用 API Gateway 与 Lambda 上传图片到 S3 这篇文章透过 Postman 将 CSDN 的图片上传到 Amazon S3 图片库;很明显的这只是个测试后端的功能是否达到功能,本篇文章将加上一个静态网页,让一般用户可以透过Web 用户端的浏览器,直觉的将 CSDN 的图片上传到 Amazon S3 图片库,如 2.号路线所示。

在这里插入图片描述
图 1. 在 Learner Lab 中透过 API Gateway 与 Lambda 上传图片架构图

步骤 1. 撰写 HTML 网页

很简单的一个画面,只有三个区块:

  • 选择图档
  • 显示图档
  • 显示图档的 base64 编码结果

主要的代码在 index2AWS.js 这个 JavaScript 原始档中。

在这里插入图片描述
图 2. 在 Learner Lab 中透过 API Gateway 与 Lambda 上传图片架构图

uploadBase64Img2AWS.html 网页代码如下

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <title>Base64 File Upload</title>
    </head>
    <body>
        <div style="margin: 24px">
            <h2>Upload Image</h2>
        </div>
        <div style="margin: 16px; padding: 16px">
            <input
                class="form-control form-control-lg"
                id="selectAvatar"
                type="file"
            />
            <button onclick="sendJSON()">Send JSON</button>

	    <p class="result" style="color:green"></p>
        </div>
        <div class="container">
            <div class="row">
                <div class="col">
                    <h6>Image Preview:</h6>
                    <img class="img" id="avatar" />
                </div>
                <div class="col">
                    <h6>Base64 Output</h6>
                    <textarea id="textAreaExample" rows="30" cols="50"></textarea>
                </div>
            </div>
        </div>
        <script src="./index2AWS.js"></script>
    </body>
</html>

步骤 2. 撰写 JavaScript 代码

index2AWS.js 主要功能有:

  • convertBase64: 将图片转成 base64格式。
  • uploadImage: 将本机图片显示在网页上。
  • sendJSON: 将 base64 格式的图片以 JSON 的形式传给 API Gateway。

代码如下:

const input = document.getElementById("selectAvatar"); //选择档案
const avatar = document.getElementById("avatar"); // 显示图片区
const textArea = document.getElementById("textAreaExample"); // base64显示区
const result = document.querySelector('.result');
let uploadFileName = "";
//读取档案,会有 base64 的格式回传
const convertBase64 = (file) => {
    return new Promise((resolve, reject) => {
        const fileReader = new FileReader();
        fileReader.readAsDataURL(file);

        fileReader.onload = () => {
            resolve(fileReader.result);
        };

        fileReader.onerror = (error) => {
            reject(error);
        };
    });
};
// 
const uploadImage = async (event) => {
    const file = event.target.files[0];
    console.log(file)
    uploadFileName = file.name
    const base64 = await convertBase64(file);
    avatar.src = base64;
    textArea.innerText = base64;
};

function sendJSON(){
	let xhr = new XMLHttpRequest();
	let url = "API Gateway endpoint 节点写在这里";
	
	// 对 API Gateway 发出 post 请求
	xhr.open("POST", url, true);
	
	// 指定请求文件格式为 application/json
	xhr.setRequestHeader("Content-Type", "application/json");
	
	// Create a state change callback
	xhr.onreadystatechange = function () {
	    if (xhr.readyState === 4 && xhr.status === 200) { //成功响应
        console.log('success');
        result.innerHTML = this.responseText;
	    } else { //请求失败
		    console.log('fail');
	    }
	};

	// Converting JSON data to string
	var data = JSON.stringify({ [uploadFileName]: textArea.value });
	// Sending data with the request
  xhr.send(data);
}
input.addEventListener("change", (e) => {
    uploadImage(e);
});

修改完毕后单击 Deploy (布署),必须要先布署才算是将代码布署到云计算中。

步骤 3. 上传到 S3 存储桶

AWS 网页控制台 上方的搜寻图示中输入 S3 ,单击 S3 服务,如下图所示。

在这里插入图片描述
图 3. AWS 网页控制台中找寻 S3 服务

开启 使用 Learner Lab - 使用 API Gateway 与 Lambda 上传图片到 S3 建立的 lambda2s3image 存储桶,单击上传按钮。

在这里插入图片描述
图 4. 进入 lambda2s3image 存储桶

将步骤 1, 2 所建立的档案 uploadBase64Img2AWS.htmlindex2AWS.js 拖拽到视窗中,上传时注意打开权限设定,这样才能让这两个档案可以变成静态网页。

权限

  • 预定义 ACL: 授予公开读取访问权限
  • 勾选 我明白授予对指定对象的公开读取访问权限的风险。

在这里插入图片描述
图 5. S3 存储桶上传权限配置

步骤 4. 打开静态网页

回到 S3 主控制介面,单击静态网页档 uploadBase64Img2AWS.html,如下图所示。

在这里插入图片描述
图 6. S3 存储桶主控制介面

进入 S3 对象主控制页面,不要单及右上角的 打开 按钮,因为那是带有权限的开启,在没登录的情况下示没法观看的,而这次做的是公开的静态网页,所以直接复制右下方的对象URL。

在这里插入图片描述
图 7. S3 对象主控制介面

在空白网址上开启,如下图,选择 CSDN 的图片准备进行上传,图片内容如下。

  1. S3所提供的静态网页网址
  2. 选择的图片名称
  3. 图片预览
  4. 图片转换的 base64 格式

在这里插入图片描述
图 8. 上传图片前端画面

对比于使用 Python 的 base64 转换(如下图),可以发现 JavaScript 转换出来的 base64 格式在逗点 (,) 前面多了 data:image/jpeg;base64 这些描述性文字,因此,需要细微修改 AWS Lambda 的代码,来符合前端页面请求的异动。

步骤 5. 修改 AWS Lambda 代码

因为前端页面有了两个部分的异动:

  1. 会提供不同的档名。
  2. base64 转换格式不同。

所以接著来把 使用 Learner Lab - 使用 API Gateway 与 Lambda 上传图片到 S3 中的 AWS Lambda 做必要的调整。
主要就是第 21 行取得上传的文件名,以及第 25 行只取逗号后面的 base64 编码数据,如下图所示。

在这里插入图片描述
图 9. 调整 AWS Lambda 代码

详细代码如下。

import json
import base64
import boto3

# base64 字符串转换后的图片
image_filename = '/tmp/inputimage.jpg'
# 存放图片的 S3 存储桶 
output_bucket = 'lambda2s3image'
# 存放在 S3 存储桶中的档案名称
# s3_key_value = 'apigateway2S3.jpg'
s3_key_value = ''

s3_client = boto3.client('s3')

def lambda_handler(event, context):
  requestMethod = event['httpMethod']
  # HTTP 请求方式为 POST 才做后续处理
  if requestMethod=='POST':
    # 将上传的 JSON 字符串转换成字典
    requestBody = json.loads(event['body'])
    key = list(requestBody.keys())[0]
    # 将上传的 base64 字符串转换成字组,再转换成 binary 格式
    print(key)
    s3_key_value = key
    image_64_decode = base64.decodebytes(requestBody[key].split(',')[-1].encode())
    # 暂存在 Lambda 的文件系统中
    image_result = open(image_filename, 'wb')
    image_result.write(image_64_decode)
    image_result.close()
    # 上传到 S3 存储桶
    s3_client.upload_file(image_filename, output_bucket, s3_key_value,ExtraArgs={'ACL': 'public-read','ContentType':'image/jpeg'})
    s3_url = 'https://' + output_bucket + '.s3.amazonaws.com/' + s3_key_value
    return {
        'statusCode': 200,
        'body': s3_url
    }
  else:
  # HTTP 请求方式非 POST 回传错误
    return {
        'statusCode': 200,
        'body': 'method error'
    }

步骤 6. 修改 API Gateway 的跨域存取

最后只要修改 API Gateway 的跨域存取就可以了,因为 S3 静态网页的所在地址与 API Gateway 不同,所以会出现跨域存取的错误,所以需要在 API Gateway 的 CORS 选项中,在访问控制允许的来源加入S3 静态网页所在的网域即可,本例的网域是 https://lambda2s3image.s3.amazonaws.com,可以透过 配置 按钮进行修改。

在这里插入图片描述
图 10. 修改 API Gateway 的跨域存取

步骤 7. 完成静态网页的图片上传

回到步骤 4 的画面,单击 Send JSON 按钮,下方开启 Web 开发工具,可以看出代码的运行状况,成功后(Success)会显示图片所在网址,只要单击该网址就可以观看所上传的图片
在这里插入图片描述
图 11. 完成静态网页的图片上传

注意一点,这样的配置是十分危险的,因为没有任何鉴权管控,表示任何人都可以透过这个网页上传图片,所以实际操作时务必搭配密钥或是权帐进行授权的动作。

感谢亚马逊云科技王向炜 Alan Wang 提供的协助。

参考资料

  • Configuring CORS for an HTTP API, https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-cors.html
  • Reason: CORS header ‘Access-Control-Allow-Origin’ missing, https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS/Errors/CORSMissingAllowOrigin
  • AWS Upload Image to S3 via ApiGateway & Lambda, https://github.com/imran9m/aws-api-lambda-s3-image-upload
  • Serverless web application for uploading files to S3, https://github.com/evanchiu/serverless-galleria/tree/master/uploader
  • 使用 Learner Lab - 使用 Lambda 转换图片为 base64 格式, https://blog.csdn.net/m0_50614038/article/details/128075734
  • 使用 Learner Lab - 使用 AWS Lambda 将图片写入 S3, https://blog.csdn.net/m0_50614038/article/details/128122934
  • 使用 Learner Lab - 使用 API Gateway 触发 AWS Lambda, https://blog.csdn.net/m0_50614038/article/details/128155030

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/58923.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

分割研究~~总结

搬来了基于实例分割的最新进展和发展历程&#xff0c;首先介绍了实例分割的基本逻辑,总结了目前主要研究方法及其原理和网络架构&#xff0c;对已发表的主流实例分割方法进行分析&#xff0c;最后对实例分割任务目前面临 的问题以及未来的发展趋势做出了分析,并针对所面临的问题…

磨金石教育插画干货分享|日本插画为什么独树一帜,那么受欢迎

插画的起源很早&#xff0c;在人类诞生文明的初级阶段&#xff0c;就有了岩画与壁画。在古典文明时代&#xff0c;中国印刷行业有了较大的发展&#xff0c;与之伴随的就是插画的长足发展。中国文化对日本起到了极大的影响。 在插画领域也是如此&#xff0c;客观的说&#xff0c…

CCF走进高校

CCF走进高校&#xff08;山东大学-人机专委&#xff09; 陶建华 人工智能与智能交互 人工智能的能力体系 感知智能&#xff1a;发展较快&#xff0c;人机交互场景运用较多&#xff1b; 认知智能&#xff1a;发展相对不成熟。 此外&#xff0c;专用智能领域发展较快&#xff0…

shell编程(一)

shell 简介 Shell 是一个用 C 语言编写的程序,一般我们说的shell编程&#xff0c;是指编写shell脚本。 Shell 负责完成用户与内核之间的交互&#xff08;shell是一个命令解释器&#xff0c;负责将用户的命令解析成操作系 统所能理解的指令&#xff09; 第一个shell脚本 创建…

Vue刷新后页面数据丢失问题的解决过程

在做vue项目的过程中有时候会遇到一个问题,就是进行F5页面刷新的时候,页面的数据会丢失,这篇文章主要给大家介绍了关于Vue刷新后页面数据丢失问题的解决过程,需要的朋友可以参考下&#xff01; 一、为什么刷新后数据会丢失 vuex存储的数据只是在页面中&#xff0c;相当于全局变…

[附源码]计算机毕业设计学习帮扶网站设计与实现Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Linux文件系统调用接口文件描述符的理解

&#x1f9f8;&#x1f9f8;&#x1f9f8;各位大佬大家好&#xff0c;我是猪皮兄弟&#x1f9f8;&#x1f9f8;&#x1f9f8; 文章目录一、对系统调用进行封装的理由二、文件的系统调用接口① openopen的选项--位图open的权限程序中设置umask权限掩码②close③write④read三、…

字节输入流【InputStream】(读文件)

字节输入流【InputStream】 java.io.InputStream 抽象类是表示字节输入流的所有类的超类&#xff0c;可以读取字节信息到内存中。它定义了字节输入流的基本共性功能方法。 public void close(): 关闭此输入流并释放与此流相关联的任何系统资源。 public abstract int read(): …

Telegraf

Telegraf是什么&#xff1f; Telegraf 是 InfluxData 公司开源的一款十分流行的指标采集软件&#xff0c;可以从数据库、系统和物联网传感器收集和发送度量和事件&#xff0c;它用Go编写&#xff0c;编译成一个没有外部依赖的二进制文件–需要非常少的内存&#xff0c;相…

数仓建模理论(一)

学习目录一、关系建模与维度建模二、维度表和事实表&#xff08;重点&#xff09;三、事实表类型四、维度模型分类一、关系建模与维度建模 &#xff08;1&#xff09;关系建模 关系建模将复杂的数据抽象为两个概念——实体和关系&#xff0c;并使用规范化的方式表示出来。关系…

【计算机毕业设计】73.房屋租赁系统求租合同源码

一、系统截图&#xff08;需要演示视频可以私聊&#xff09; 摘 要 随着科学技术的飞速发展&#xff0c;社会的方方面面、各行各业都在努力与现代的先进技术接轨&#xff0c;通过科技手段来提高自身的优势&#xff0c;房屋租赁系统当然也不能排除在外。房屋租赁系统是以实际…

Mybatis源码解析(八):插件机制

Mybatis源码系列文章 手写源码&#xff08;了解源码整体流程及重要组件&#xff09; Mybatis源码解析(一)&#xff1a;环境搭建 Mybatis源码解析(二)&#xff1a;全局配置文件的解析 Mybatis源码解析(三)&#xff1a;映射配置文件的解析 Mybatis源码解析(四)&#xff1a;s…

flex布局列表页(一行内容比较多,长度比较长)

一、Flex 布局是什么&#xff1f; Flex 是 Flexible Box 的缩写&#xff0c;意为"弹性布局"&#xff0c;用来为盒状模型提供最大的灵活性。任何一个容器都可以指定为 Flex 布局。 二、基本概念 采用 Flex 布局的元素&#xff0c;称为 Flex 容器&#xff08;flex co…

Java开发必须掌握的运维知识 (九)-- Docker容器监控信息可视化仪表:Grafana

一、Grafana 是用来干什么的&#xff1f; Grafana 是一个监控仪表系统&#xff0c;它是由 Grafana Labs 公司开源的的一个系统监测 (System Monitoring) 工具。它可以大大帮助你简化监控的复杂度&#xff0c;你只需要提供你需要监控的数据&#xff0c;它就可以帮你生成各种可视…

jdk11新特性——JShell交互性工具

目录一、jshell概述二、jshell位置三、jshell示例3.1、示例一&#xff08;声明变量并赋值&#xff09;3.2、示例二&#xff08;输出打印内容&#xff09;3.3、示例三&#xff08;帮助命令&#xff09;一、jshell概述 java9引入了jshell这个交互性工具&#xff0c;让Java也可以…

BUUCTF Misc 黑客帝国 [MRCTF2020]你能看懂音符吗 [HBNIS2018]caesar [HBNIS2018]低个头

黑客帝国 下载文件 一长串16进制&#xff0c;复制到在线16进制转文本 很明显是一个RAR文件&#xff0c;使用脚本将16进制转换成文件 import binasciihex_data这里填十六进制数据 outopen(res.rar,wb) out.write(binascii.unhexlify(hex_data)) out.close() 需要密码&#xff…

[附源码]计算机毕业设计校园疫情防范管理系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

# 智慧社区管理系统-核心业务管理-03投诉信息

一 后端 1:entity package com.woniu.community.entity;import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;Data AllArgsConstructor NoArgsConstructor public class Complaint {private int id;private int comId;private String c…

多功能跑步机外观及结构设计

目 录 摘 要 I Abstract II 第1章 绪论 1 1.1背景及意义 1 1.2国内外发展情况 2 1.3研究主要内容 3 第2章 多功能跑步机结构设计 5 2.1 传动机构设计 5 2.1.1 设计步骤及参数选择 5 2.1.2多楔带带轮结构和尺寸选择 8 2.2 电动机类型与参数的选择 10 2.2.1类型功率选择 10 2.2.2…

连连看核心算法与基本思想(附全部项目代码链接与代码详细注释)

文章目录0.说明1.基本要求2.思路分析(加入核心代码)2.1 游戏初始化局面2.2 两点是否可连2.3 游戏是否结束2.4 判断死锁3.注意事项与全部代码0.说明 对于数据结构和算法&#xff0c;我并不是很精通&#xff08;真的很一般&#xff09;&#xff0c;因此在这里只是做一个自己的简…