当前位置: 代码网 > it编程>编程语言>Java > 使用 Learner Lab - 使用 S3 静态网页上传图片,搭配 API Gateway 与 Lambda

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

2024年07月31日 Java 我要评论
AWS Academy Learner Lab 是提供一个帐号让学生可以自行使用 AWS 的服务,让学生可以在 100 USD的金额下,自行练习所要使用的 AWS 服务,如何进入 Learner Lab 请参考 使用 Learner Lab - 学生,而这篇文章是使用 S3 静态网页上传图片,搭配 API Gateway 与 Lambda,完整的介绍前后端的交互。下图中的 1.号路线就是 使用 Learner Lab - 使用 API Gateway 与 Lambda 上传图片到 S3 这篇文章透过 Pos

使用 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
(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com