从 s3 静态网站获取 Lambda 函数,通过 API 网关,给出 415 Unsupported Media Type 错误

Fetch from s3 static website to Lambda function, through API Gateway, gives 415 Unsupported Media Type error

我正在尝试通过 API 从我的 s3 托管静态网站获取(方法 POST)到我的一个 lambda 函数,运行时间语言是 nodejs网关。

按照关于 HTML post 表单的代码片段,执行 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>&nbsp;<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 角色中),就好像我测试网关插入格式为 body 的请求 [=71] =],查询成功插入数据库。 这里有一个响应屏幕,以及响应 Header :

指定我在 API 上启用了 CORS,并且我的 header 响应包含 AllowControlallowOrigin : *.

尽管如此,当我尝试通过主页 运行 我的请求时,我得到了这个错误

如果我尝试在 JS 中插入模式:no-cors,我会收到此错误: POST net::ERR_ABORTED 415(不支持的媒体类型。

所以我找到了一些线程,其中解释了模式:no-cors 我的 form-data 在 text/char,而不是网关期望的 application/json成为。 (网关具有内容类型 application/json 的集成请求(Lambda 类型)的映射模板)

我尝试将映射模板 body 内容类型更改为 text/char,然后从 ---> 更改为:

现在,正如我们预期的那样,从我们的第一个错误中可以看出,启用模式:no-cors 将导致不透明的响应:

所以我不知道该怎么做以及是什么导致了我的问题。首先,我不明白为什么当我从网关启用 CORS 时它会提示我有关 CORS 的错误,甚至响应 Header 包含 AllowControlAllowOrigin : *.

我还尝试在 s3 存储桶选项错误页面中添加 index.html,正如有人建议的那样作为不透明响应的解决方案,但我得到

最后我需要做的就是:将 Origin 添加到 API -> Enable Cors -> Allow Control Allow headers.