Day 32 - 透过手机呼叫 Amazon API Gateway 上传图片到 S3

Day 31 - 使用 Amazon API Gateway 上传图片到 S3 演示了如何透过 API Gateway 直接上传一个图片到 S3,但如果要让手机也可以上传图片的话,那必须让这个 API Gateway 所实作的 REST API 可以有跨预存取 (CORS) 的功能,这篇文章的目的为:

  1. 打开跨预存取 (CORS) 的功能。
  2. 使用 curl 指令验证跨预存取的功能。
  3. 如何针对 API Gateway 除错,使用 Cloudwatch Logs。
  4. 实作一个网页进行跨预存取 (CORS) 的操作。

持续 Day 31 - 使用 Amazon API Gateway 上传图片到 S3 的操作,在 {object} 资源上,点击 操作 选择 启用 CORS 进入设定画面,只要点击 启用 CORS 并取代现有的 CORS 标题 按钮,即可,如下图所示。


图 1、启用跨预存取 (CORS) 的功能

弹出一个确认视窗,直接点击 是,取代现有数值 即可,如下图所示。主要是会增加一个 OPTIONS 的方法,并在该方法内添加 Access-Control-Allow-Headers, Access-Control-Allow-Methods, Access-Control-Allow-Origin 等回应标头,以及在 PUT 方法中,添加 Access-Control-Allow-Origin 回应标头,原理部分可以参阅 Day 09 - Amazon Linux 2 上解决跨来源资源共用 (CORS) 与开机自动启动 uwsgi 这篇文章。


图 2、启用跨预存取 (CORS) 的确认画面

使用 curl 指令来验证 OPTIONS 方法的正确性,指令如下。

curl -v -X OPTIONS https://q56fxsgl10.execute-api.ap-southeast-1.amazonaws.com/v1/yehfishbucket/123.jpg

从下图来看,送出去的请求与回应,回应部分与预期的结果不同,是错误码 500,这表示伺服器内发生错误,这是一个很麻烦的事情,因为这是在云端的托管服务,要如何除错?


图 3、curl 指令验证 OPTIONS 方法

CloudWatch 是云端开发最主要的除错工作,可以看到任何的运算结果,但预设都是不开放的,因为开放记录要占用空间与算力,所以都是要收费的,开发过程中是不得不打开这个功能,于是在左侧的功能导览列中,选择 阶段,并点击 v1,在右手边的主要画面里,选择 日志/追踪 页签,找到 CloudWatch 设定,勾选 启用 CloudWatch 日志,并在 日志等级 中,选择 INFO,勾选 记录完整请求/回应资料,最后点击 储存变更 按钮,如下图所示。


图 4、API Gateway 启用 CloudWatch 日志功能

打开 CloudWatch 控制台,在左边功能导览列中,选择 日志群组,可以在右边主画面中找到对应的日志群组,前缀词就是 API-Gateway-Execution-Logs,而最后内容可以在 叫用 URL 中 URL 的前面的编号中找到,如下图所示。


图 5、CloudWatch 日志画面

接着记得在重新执行一次 curl 指令,根据时间找到最接近的一次记录时间,如下图所示。


图 6、进入特定的日志群组,根据时间锁定要观察的 CloudWatch 日志

观看整个 API Gateway 的呼叫过程,建议从得到 OPTIONS 请求开始,发现错误的是倒数第三行,可以点击倒三角形图示,会显示详细内容,如下所示:

(24f5f845-ca32-40ad-bdd7-5f0b70adcf11) Execution failed due to configuration error: Unable to transform request

根据字面意思似乎是转换内容格式出错,因为 OPTIONS 只是用来预检验用 (preflight) 的请求,并没有内容 (BODY),所以正常来说是不需要进行内容编码的,所以猜测是编码设定出错。


图 7、CloudWatch 日志的详细讯息

进入 API Gateway 的 设定页面,找到二进位媒体类型,将原先的 */* 改成 image/*,也就是只针对请求标题 Content-Type 中值设定为 image 的内容,才进行二进位媒体类型编码,设定完成后,记得点击 储存变更 按钮,如下图所示。


图 8、Amazon API Gateway 中针对二进位媒体类型的设定

务必要在重新部署后,再执行一次 curl 的检验,此时可以发现回应码变成 200 的成功回应,且也有出现 Access-Control-Allow-Headers, Access-Control-Allow-Methods, Access-Control-Allow-Origin 等回应标头,如下图所示。


图 9、curl 的检验结果画面

补充说明一下,要如何调整 OPTIONS 的回应表头,回到方法的整合画面中,可以看到在整合请求中是透过 MOCK ,一个模拟的整合请求,也就是不会接到任何服务,预估先前的错误应该是在方法请求转到整合请求中出错的。接着点击 整合回应 ,如下图所示。


图 10、OPTIONS 的整合画面

如果在上面的请求中都没有出错的话,正常应该就是回传状态码 200,在整合回应中,指定标题映射,既然是映射,表示真正的配置不在这里,而是在方法回应中设定回应标头的名称,而在这里指定回应的映射值,以下两图表明两者之间的关系,如果要新增回应标头,需要在方法回应中新增,然而,标头内的值,则是在整合回应中指定。


图 11、OPTIONS 的整合回应


图 12、接着选择 OPTIONS 的方法回应


图 13、OPTIONS 的方法回应设定画面

确认可以进行跨预存取后,直接使用网页来进行测试,下图中的网址栏中可以显示出这是以本地的方式开启这个档案,并打开开发者工具,以观察程式运作情形。以下为范例程式,注意的是 API_ENDPOINT 这个变数要放的内容除了部署的 URL 外,还要加上存储桶的名称,而上传的档名,会自动抓取,所以不用事先输入。

<!DOCTYPE html>
<html><head><meta charset="utf-8"/><title>Upload file to S3</title><script src="https://unpkg.com/vue"></script><script src="https://unpkg.com/axios@0.2.1/dist/axios.min.js"></script></head><body><div id="app"><h1>S3 Uploader Test</h1><div v-if="!image"><h2>Select an image</h2><input type="file" @change="onFileChange"></div><div v-else><img :src="data:image" /><button v-if="!uploadURL" @click="removeImage">Remove image</button><button v-if="!uploadURL" @click="uploadImage">Upload image</button></div><h2 v-if="uploadURL">Success! Image uploaded to bucket.</h2></div><script>const MAX_IMAGE_SIZE = 10000000/* ENTER YOUR ENDPOINT HERE */const API_ENDPOINT = 'API Gateway的存取点' // e.g. https://q56fxsgl10.execute-api.ap-southeast-1.amazonaws.com/v1/yehfishbucket/ [API URL+bucket]uploadFile=''new Vue({el: "#app",data: {image: '',uploadURL: ''},methods: {onFileChange (e) {let files = e.target.files || e.dataTransfer.filesif (!files.length) returnfor( attr in files[0])console.log(attr)console.log(files[0].name)uploadFile = files[0].namethis.createImage(files[0])},createImage (file) {// var image = new Image()let reader = new FileReader()reader.onload = (e) => {console.log('length: ', e.target.result.includes('data:image/jpeg'))if (!e.target.result.includes('data:image/jpeg')) {return alert('Wrong file type - JPG only.')}if (e.target.result.length > MAX_IMAGE_SIZE) {return alert('Image is loo large.')}this.image = e.target.result}reader.readAsDataURL(file)},removeImage: function (e) {console.log('Remove clicked')this.image = ''},uploadImage: async function (e) {console.log('Upload clicked')console.log('Uploading: ', uploadFile)//this.image)let binary = atob(this.image.split(',')[1])let array = []for (var i = 0; i < binary.length; i++) {array.push(binary.charCodeAt(i))}let blobData = new Blob([new Uint8Array(array)], {type: 'image/jpeg'})this.uploadURL = API_ENDPOINT + uploadFileconsole.log('Uploading to: ', this.uploadURL)const result = await fetch(this.uploadURL, {method: 'PUT',body: blobData})console.log('Result: ', result)// Final URL for the user doesn't need the query string params//this.uploadURL = uploadURL.split('?')[0]}}})</script><style type="text/css">body {background: #20262E;padding: 20px;font-family: sans-serif;}#app {background: #fff;border-radius: 4px;padding: 20px;transition: all 0.2s;text-align: center;}#logo {width: 100px;}h2 {font-weight: bold;margin-bottom: 15px;}h1, h2 {font-weight: normal;margin-bottom: 15px;}a {color: #42b983;}img {width: 30%;margin: auto;display: block;margin-bottom: 10px;}</style></body>
</html>


图 14、实作 CORS 的上传网页

最后再检查 S3 确认是否上传成功,如下图所示。


图 15、Amazon API Gateway 管理控制台介面

参考资料

  • How do I upload an image file to Amazon S3 through API Gateway?, https://aws.amazon.com/tw/premiumsupport/knowledge-center/api-gateway-upload-image-s3/
  • 存储桶政策范例, https://docs.aws.amazon.com/zh_tw/AmazonS3/latest/userguide/example-bucket-policies.html
  • Uploading to Amazon S3 directly from a web or mobile application, https://aws.amazon.com/tw/blogs/compute/uploading-to-amazon-s3-directly-from-a-web-or-mobile-application/
  • S3 presigned URLs with SAM, auth and sample frontend, https://github.com/aws-samples/amazon-s3-presigned-urls-aws-sam
  • Serverless File Uploads using S3 and Lambda, https://www.youtube.com/watch?v=mw_-0iCVpUc

Day 32 - 透过手机呼叫 Amazon API Gateway 上传图片到 S3相关推荐

  1. Day 31 - 使用 Amazon API Gateway 上传图片到 S3

    Day 31 - 使用 Amazon API Gateway 上传图片到 S3 建立 S3 存储桶 (bucket),关闭封锁所有公开存取权,并设定一个资料夹允许对外公开读取. 建立 IAM 的角色: ...

  2. AWS Lambda 搭配 Amazon API Gateway (HTTP API)

    AWS Lambda 搭配 Amazon API Gateway (HTTP API) AWS Lambda 是一种无伺服器.事件推动的运算服务,而 Amazon API Gateway 可以让开发人 ...

  3. AWS Lambda 搭配 Amazon API Gateway (REST API)

    AWS Lambda 搭配 Amazon API Gateway (REST API) AWS Lambda 是一种无伺服器.事件推动的运算服务,而 Amazon API Gateway 可以让开发人 ...

  4. Day 30 - 实作 Amazon API GateWay 整合 AWS Lambda 与 Dynamodb

    Day 30 - 实作 Amazon API GateWay 整合 AWS Lambda 与 Dynamodb Amazon API GateWay 简介 Amazon API Gateway 是由 ...

  5. Amazon API Gateway使用IP白名单控制后端服务访问

    一图胜千言 目标 我们需要在Amazon API Gateway设置资源策略,用于控制某些IP段能够访问特定后端服务. 前提 假设已经完成了Amazon API Gateway中REST API的接口 ...

  6. 如何从Amazon API Gateway将查询字符串或路由参数传递到AWS Lambda

    本文翻译自:How to pass a querystring or route parameter to AWS Lambda from Amazon API Gateway for instanc ...

  7. websockets_如何将WebSockets与AWS API Gateway和Lambda一起使用来构建实时应用程序

    websockets by Janitha Tennakoon 通过詹妮莎·特纳库恩 如何将WebSockets与AWS API Gateway和Lambda一起使用来构建实时应用程序 (How to ...

  8. aws lambda使用_使用Lambda,Api Gateway和CloudFormation在AWS云上使用Java

    aws lambda使用 在上一篇文章中,我们实现了基于Java的aws lambda函数,并使用CloudFront进行了部署. 由于我们已经设置了lambda函数,因此我们将使用AWS API G ...

  9. 使用Lambda,Api Gateway和CloudFormation在AWS云上使用Java

    在上一篇文章中,我们实现了基于Java的aws lambda函数,并使用CloudFront进行了部署. 由于我们已经设置了lambda函数,因此我们将使用AWS API Gateway将其与http ...

最新文章

  1. JAVA数组的定义及用法
  2. 开发Activex控件安全
  3. python常用内置函数总结-Python学习教程之常用的内置函数大全
  4. 产品管理|产品设计流程[完整版]
  5. JAVA学习笔记系列4-Eclipse版本选择
  6. Java并发编程之CountDownLatch源码解析
  7. IdentityServer4【QuickStart】之使用asp.net core Identity
  8. HDU 折线分割平面
  9. linux uucp 改为 root,ubuntu 10.04 /etc目录下找不到vsftpd.user_list和vsfepd.ftpusers两个文件?...
  10. 在.Net中进行SQL Server数据库备份与还原操作实用类
  11. 【Hoxton.SR1版本】Spring Cloud Gateway之Filter详解
  12. 美通企业日报 | 易车收到腾讯等私有化要约;沃尔玛中国推出快时尚品牌George...
  13. pytorch和python的区别_Keras和PyTorch的视觉识别与迁移学习对比
  14. 王之泰201771010131《面向对象程序设计(java)》第三周学习总结
  15. idea Ctrl+Alt+T 快捷键失效、无法弹出surround with、与qq热键冲突-解决办法
  16. 09、Flutter FFI Dart Native API
  17. 腾讯云轻量应用服务器如何创建并挂载云硬盘?
  18. iPhone信号太差?学会这三招,信号差也能瞬间满格!
  19. 微积分的历史(二):起源之牛顿
  20. [原]解密Airbnb 自助BI神器:Superset 颠覆 Tableau

热门文章

  1. win7系统如何关闭广告弹窗操作方法教学
  2. 2020-10-26可转债新规
  3. linux 儒略日时间计算,儒略日(儒略日 在线计算器)
  4. 想不想修真鸿蒙之礼奖励,想不想修真论道之礼额外奖励获取攻略
  5. SVM 美国威斯康星州乳腺癌检测
  6. 剑指 Offer 58 - II. 左旋转字符串
  7. android 插入耳机 使用自身mic录音_苹果iPhone 12携最新系统强势登场,10款主流TWS耳机兼容性测试...
  8. Arduino基础入门套件教程PDF
  9. 使用JAVA程序片段动态生成表格
  10. logo在线生成怎么操作?手机也能轻松生成