Amazon web services Vue&;Axios+;AWS API网关和;Lambda-CORS+;岗位不工作

Amazon web services Vue&;Axios+;AWS API网关和;Lambda-CORS+;岗位不工作,amazon-web-services,vue.js,aws-lambda,axios,aws-api-gateway,Amazon Web Services,Vue.js,Aws Lambda,Axios,Aws Api Gateway,我试图通过AWS API网关创建一个API测试函数,并通过Axios的Vue应用程序调用一个Lambda函数。它应该从输入元素发送名称和电子邮件。每次我收到此错误时: Access to XMLHttpRequest at '[API Gateway URL]' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access

我试图通过AWS API网关创建一个API测试函数,并通过Axios的Vue应用程序调用一个Lambda函数。它应该从输入元素发送名称和电子邮件。每次我收到此错误时:

Access to XMLHttpRequest at '[API Gateway URL]' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
我已经在API网关设置()中的每个步骤/资源上启用了CORS。以下是Vue组件的代码:

<template>
<div data-app>
        <div class="cell" id="testForm">
    {{responseMsg}}

       <label>Name</label>
       <input v-model="name" type="text" placeholder="Name">
       <label>Email Address</label>
       <input v-model="email" type="email" placeholder="Email Address">
       <button v-on:click="formFunction">Submit</button>
   
   </div>
</div>
</template>

<script>
import axios from 'axios';

export default {
    name: "formtest",
    data: function () {
        return {name: '',
        email: '',
        responseMsg: 'No response yet!'}
    },
    methods: {
        formFunction: function () {
            const formObj = {
                name: this.name,
                email: this.email
            }
            const reqURL = [API gateway URL];
            axios.post(reqURL, formObj)
    .then(response => {
        console.log(response);
        });

        }
    }
}

</script>
我在这里做错了什么?

注意:

  • 我下面的答案是针对一个像你这样的问题(我的),但是有一个需要验证的路由(例如Cognito)。在任何情况下,解决方案也适用于您的情况
  • 如果我没有弄错的话,您的axios请求具有/request JSON数据类型,这使得它成为一个“非简单请求”(详见下面的链接)
  • 您的问题与Vue或Axios无关(我使用的是相同的)。
回答

在某些情况下,POST/GET请求将成为非简单请求

该非简单请求将向同一目的地发出飞行前选项请求,以验证某些内容,如果对响应满意,则执行原始请求

如果路径(API_url/private)需要身份验证,则选项请求将失败,并且您将永远无法*设法通过POST/get请求

如果路径不需要身份验证,但对选项的响应不提供CORS响应,则选项请求将失败,并且您将永远无法*设法通过POST/get请求

*
如果使用在浏览器上运行的东西,因为浏览器非常关心CORS。如果您在浏览器之外(例如使用“curl”),您的请求将有效,因为它不关心CORS响应/参数

解决方案很简单,但并不明显:

如果你有

route       verb            Authentication      integration
/private    POST/GET        yes                 lambda-private
然后你需要创建一个额外的

route       verb            Authentication      integration
/private    POST/GET        yes                 lambda-private
/private    OPTIONS         no                  lambda-CORS-response
因此,您的飞行前请求将得到良好的响应,POST/get请求将到达您想要的目的地

这些是集成(使用不同的lambda)

这里是授权人(只有岗位有授权人)

如果您这样做,它将参与所有选项,而不考虑路线(未验证)

这里对此进行了解释,但他们并没有说您需要创建“额外的lambda函数”来响应该路由/动词

路线

在找到解决方案之前,我一直在探索其他选择。以下是我的发现。 如果有人发现信息是错误的(索赔需要以某种方式进行备份),他们会非常乐意更正信息


问:我使用的是“HTTP API”(AWS)。我需要切换到“RESTAPI”来解决这个问题吗

A:在某个阶段我也这么认为。但是没有,只需按照上面的说明操作即可

然而,“restapi”有更多的选项(它们的成本也更高),并且您可能不需要执行上面描述的操作。如果有人对此有见解,我很乐意更新这一部分。然而,拥有更多选项也可能意味着“设置更复杂”


问:如果我需要自己提供CORS响应,那么API上的CORS配置是什么

答:显然只有“200型”回答。->

只有当我自己提供CORS响应时,我的功能才起作用


问:我可以通过在GET而不是POST中提交数据来避免飞行前选项请求吗

答:不,如果您的请求符合非简单请求的条件,则无论如何都会发生


问:为什么我的应用程序/网页中使用Axios的POST/GET请求失败,并抱怨CORS,但“curl”运行正常

答:“curl”不关心CORS,浏览器非常关心CORS。
至少“curl”允许您知道“某些东西正在工作”,但您需要做一些额外的工作才能完全正确。

您是否在服务器中启用了CORS for POST方法?您是否尝试发送内容类型标题?axios.defaults.headers.post['Content-Type']='application/x-www-form-urlencoded';检查以确保在API网关中设置的URL与Axios调用的URL完全相同。因为Axios发出的第一个请求是CORS飞行前请求,例如,如果您调用了错误的URL,您将得到一个CORS失败错误,而不是404找不到错误。虽然它应该自动发生,但如果您在AWS控制台中创建资源,请检查是否配置了
选项
方法。
route       verb            Authentication      integration
/private    POST/GET        yes                 lambda-private
/private    OPTIONS         no                  lambda-CORS-response
route       verb            Authentication      integration
/{proxy+})  OPTIONS         no                  lambda-CORS-response