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


    使用 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 网页代码如下

    
    
        
            
            
            Base64 File Upload
        
        
            

    Upload Image

    Image Preview:
    Base64 Output
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    步骤 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);
    });
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59

    修改完毕后单击 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'
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    步骤 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
  • 相关阅读:
    ubuntu16.0安装配置openvpn,客户端在作为网关连接子网
    第八章 排序 一、排序的基本概念
    linux系统向github传文件
    Uniapp云开发(Uniapp入门)
    Axios前后端交互规范
    龙湖科技一面
    Maven历史版本下载
    电脑软件:推荐一款非常强大的pdf阅读编辑软件
    位运算相关
    【CSDN 每日一练 ★☆☆】【数论】用数组写水仙花数
  • 原文地址:https://blog.csdn.net/m0_50614038/article/details/128167047