通过 API Gateway 从 s3 静态网站获取到 Lambda 函数,给出 415 Unsupported Media Type 错误
Posted
技术标签:
【中文标题】通过 API Gateway 从 s3 静态网站获取到 Lambda 函数,给出 415 Unsupported Media Type 错误【英文标题】:Fetch from s3 static website to Lambda function, through API Gateway, gives 415 Unsupported Media Type error 【发布时间】:2021-08-02 15:25:27 【问题描述】:我正在尝试通过 API Gateway 从我的 s3 托管静态网站获取(方法 POST)到我的 lambda 函数之一,运行时语言是 nodejs。
遵循关于 html post 表单的 sn-ps、执行 post 请求并将表单数据转换为 json 的 JS 脚本,以及我的 nodejs lambda 函数。
<form name='form' id="myForm">
<div id=whatpageisit><a href='index.html'>LOGIN</a>SIGNUP </div>
<p> <label>Username <input type='text' name='username' value=''></label> </p>
<p> <label>Email <input type='email' name='email' value=''></label> </p>
<p> <label>Password <input type='password' name='password' value=''></label> </p>
<p> <label>Conferma Password <input type='password' name='conferma_password' value=''></label> </p>
<p> <div id="submit"><label> <input type='submit'></label></div> </p>
</form>
---------- JS
<script> // https://gomakethings.com/serializing-form-data-with-the-vanilla-js-formdata-object/
document.addEventListener('submit', function (event)
event.preventDefault();
fetch('',
//mode:"no-cors",
method: 'POST',
body: JSON.stringify(Object.fromEntries(new FormData(event.target))),
headers:
'Content-type': 'application/json; charset=UTF-8'
).then(function (response)
if (response.ok)
return response.json();
return Promise.reject(response);
).then(function (data)
console.log(data);
).catch(function (error)
console.warn(error);
);
);
</script>
--- 拉姆达函数
exports.handler = (event, context, callback) =>
context.callbackWaitsForEmptyEventLoop = false;
pool.getConnection(function(err,connection)
var user = event.body.username;
var email = event.body.email;
var password = event.body.password;
var sql0 = "INSERT INTO users VALUES ('"+user+"','"+email+"','"+password+"','')";
connection.query(sql0, function (error, result, fields)
connection.release();
if (error)
callback(error);
else callback(null,result);
); //end connection.query
); //end pool.getConnection
我还想澄清一下,我相信我的函数具有所有正确的权限(在与 Lambda 函数关联的 IAM 角色中),就好像我测试网关以 json 格式插入请求正文一样,查询已成功插入D B。 这里有一个响应屏幕,以及响应标题:
指定我在我的 API 上启用了 CORS,并且我的标头响应包含 AllowControlallowOrigin : *.
尽管,当我尝试通过我的主页运行我的请求时,我得到了这个错误
如果我尝试在 JS 中插入模式:no-cors,我会收到此错误: POST net::ERR_ABORTED 415(不支持的媒体类型。
所以我找到了一些线程,其中解释了 mode: no-cors 我的表单数据在 text/char 中,而不是网关期望的 application/json 中。 (网关有关于内容类型application/json的集成请求(Lambda类型)的映射模板)
我尝试将映射模板正文内容类型更改为 text/char,并从 ---> 变为:
现在,正如我们的第一个错误所预期和预期的那样,启用模式:no-cors 将导致不透明的响应:
所以我不知道该怎么做以及是什么导致了我的问题。首先,我不明白为什么当我从网关启用 CORS 时它会提示我有关 CORS 的错误,甚至响应标头包含 AllowControlAllowOrigin :*。
我还尝试在 s3 存储桶选项错误页面中添加 index.html,正如有人建议的那样作为不透明响应的解决方案,但我得到
【问题讨论】:
415错误是根本问题; CORS 消息是一个副作用。 那么问题是我如何传递表单数据,那么JS脚本呢? 我的猜测是,您使用的某种 API 的数据编码方式与 JSON 不同?如果是这种情况,那么你需要这个:docs.aws.amazon.com/apigateway/latest/developerguide/…. @MarkoE 我怎么知道它需要什么样的编码?如果我通过这种 json 请求测试我的网关 "username": "mike", "email": "mike@gmail.com", "password": "grvdsc" ,我得到 "errorMessage": "Cannot read属性 'username' of undefined",对于 HTTP 获取。昨天至少在 Gateway 上运行良好。 编码取决于您将数据传递到的后端。因此,基本上有四种类型的后端集成,如果后端可以处理 JSON 数据,则其中两种被认为是“代理”。其他两个要求您使用 VTL 重写数据(在我之前评论的链接中)。解释如下:docs.aws.amazon.com/apigateway/latest/developerguide/…. 【参考方案1】:最后我需要做的就是:将 Origin 添加到 API -> Enable Cors -> Allow Control Allow headers。
【讨论】:
以上是关于通过 API Gateway 从 s3 静态网站获取到 Lambda 函数,给出 415 Unsupported Media Type 错误的主要内容,如果未能解决你的问题,请参考以下文章
AWS S3 静态站点 CORS jquery ajax POST 到 API Gateway
AWS CDK 将 API Gateway URL 传递到同一堆栈中的静态站点
使用 Learner Lab - 使用 S3 静态网页上传图片,搭配 API Gateway 与 Lambda