【问题标题】:Vue & Axios + AWS API Gateway & Lambda - CORS + POST not workingVue 和 Axios + AWS API Gateway 和 Lambda - CORS + POST 不起作用
【发布时间】:2021-03-31 10:12:38
【问题描述】:

我正在尝试通过 AWS API Gateway 创建一个 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 网关设置 (per this article) 中的每个步骤/资源上启用了 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>

这是我的 Lambda 函数:

exports.handler = async (event) => {
    const resString = 'Hello ' + event.name + ", your email address is " + event.email

    const response = {
        statusCode: 200,
         headers: {
            "Access-Control-Allow-Headers" : "Content-Type",
            "Access-Control-Allow-Origin": "*",
            "Access-Control-Allow-Methods": "OPTIONS,POST,GET"
        },
        body: resString,
    };
    return response;
};

我在这里做错了什么?

【问题讨论】:

  • 您是否在服务器中为 POST 方法启用了 CORS?
  • 您是否尝试过发送内容类型标头? axios.defaults.headers.post['Content-Type'] ='application/x-www-form-urlencoded';
  • 检查以确保在 API Gateway 中设置的 URL 与 Axios 调用的 URL 完全相同。因为 Axios 的第一个请求是 CORS 飞行前请求,所以如果你调用了错误的 URL,你会得到一个 CORS 失败错误而不是 404 not found 错误,例如。
  • 虽然它应该自动发生,但如果您在 AWS 控制台中创建资源,请检查是否还配置了 OPTIONS 方法。

标签: amazon-web-services vue.js aws-lambda axios aws-api-gateway


【解决方案1】:

注意事项:

  • 我在下面的答案是针对像您这样的问题(我的)而写的,但路由需要身份验证(例如 Cognito)。无论如何,该解决方案也适用于您的情况。
  • 如果我没记错的话,您的 axios 请求具有/请求 JSON 数据类型,这使其成为“非简单请求”(更多内容见下方链接)。
  • 您的问题与 Vue 或 Axios 无关(我使用的是相同的)。

回答

在某些条件下,POST/GET 请求会变成非简单请求。

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

Why is an OPTIONS request sent and can I disable it?

如果路径 (API_url/private) 需要身份验证,则 OPTIONS 请求将失败,您将永远无法* 设法通过您的 POST/GET 请求。

如果路径不需要身份验证,但对 OPTIONS 的响应未提供 CORS 响应,则 OPTIONS 请求将失败,您将永远无法* 设法让您的 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)

这里是授权人(只有 POST 有授权人)

如果你这样做,它将参加所有的 OPTIONS,无论路线如何(未验证)

route       verb            Authentication      integration
/{proxy+})  OPTIONS         no                  lambda-CORS-response

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

https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-cors.html https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-cors.html

路线 https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-routes.html#http-api-develop-routes.evaluation

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


问:我正在使用“HTTP API”(AWS)。我需要切换到“REST API”来解决这个问题吗?

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

但是,“REST API”有更多选项(它们也更昂贵),也许您不需要执行上述操作。如果有人对此有见解,我很乐意更新这部分。但是,拥有更多选项也可能意味着“设置更加复杂”。


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

A:显然仅适用于“200 类型”响应。 -> https://enable-cors.org/server_awsapigateway.html

只有当我自己提供 CORS 响应时,我的函数才起作用。


问:我能否通过在 GET 而不是 POST 中提交数据来避免飞行前 OPTIONS 请求

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


问:为什么我在我的应用程序/网页中使用 Axios 的 POST/GET 请求无法抱怨 CORS,但 'curl' 会运行得很好。

A: 'curl' 不关心 CORS,浏览器非常关心。 至少“curl”可以让您知道“某事正在工作”,但您需要做一些额外的工作才能完全正确。

【讨论】:

  • 添加未经身份验证的 OPTIONS 路径一旦显而易见,就变得如此明显。我一直在敲我的头,然后我读到了,我就像,“DOH”
猜你喜欢
  • 2016-12-23
  • 2017-09-19
  • 1970-01-01
  • 2022-08-16
  • 2016-06-02
  • 1970-01-01
  • 2017-08-24
  • 1970-01-01
  • 2020-06-05
相关资源
最近更新 更多