Vue&Axios + AWS API网关&Lambda-CORS + POST无法正常工作 [英] Vue & Axios + AWS API Gateway & Lambda - CORS + POST not working

查看:95
本文介绍了Vue&Axios + AWS API网关&Lambda-CORS + POST无法正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过AWS API Gateway创建一个API测试功能,并通过一个带有Axios的Vue应用程序调用一个Lambda函数.应该从输入元素发送名称和电子邮件.每次收到此错误:

 从起源'http://localhost:8080'对'[API Gateway URL]'处的XMLHttpRequest的访问已被CORS策略阻止:对预检请求的响应未通过访问控制检查:它未通过具有HTTP正常状态. 

我已在API网关设置中的每个步骤/资源上启用了CORS(

答案

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

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

这里是授权者(只有POST才有授权者)

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

 路由动词身份验证集成/{proxy +})选项无lambda-CORS响应 

这里对此进行了某种解释,但他们并没有说您需要创建额外的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响应时,我的功能才起作用.


Q:我可以通过将数据提交到GET而不是POST中来避免出现预选项OPTIONS请求

A:不,如果您的请求满足非简单请求的条件,无论如何都会发生.


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

A:"curl"并不关心CORS,浏览器也非常关心.至少"curl"使您知道某事在起作用",但您需要做一些额外的工作才能使其完全正确.

I am trying to create an API test function via AWS API Gateway and a Lambda function that is invoked via a Vue app with Axios. It is supposed to send a name and email from input elements. Every time I receive this error:

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.

I have enabled CORS on each step/resource in the API Gateway setup (per this article). Here is the code for the Vue component:

<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>

And here is my Lambda function:

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;
};

What could I be doing wrong here?

解决方案

Notes:

  • My answer below was written to a problem (mine) like yours but with a route that needs Authentication (Cognito for example). In any case, the solution applies to your case too.
  • If I am not mistaken, your axios request has/request JSON data-type and that makes it a "non-simple request" (more on a link below).
  • Your problem is NOT related with Vue or Axios (I am using the same).

ANSWER

Under certain conditions, a POST/GET request becomes a non-simple request.

That non-simple request will do a pre-flight OPTIONS request to the same destination to verify some stuff, and if happy with the response, then do your original request.

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

If the Path (API_url/private) needs Authentication, the OPTIONS request will fail and you will never* manage to get your POST/GET request through.

If the path does not need Authentication but the response to OPTIONS does not provide a CORS response, the OPTIONS request will fail and you will never* manage to get your POST/GET request through.

* If using something running on the browser, because the browser does care very much about CORS. If you are outside the browser (using 'curl' for example) your request will work because it does not care about CORS responses/parameters.

The solution is simple but not obvious:

If you have a

route       verb            Authentication      integration
/private    POST/GET        yes                 lambda-private

Then you need to create an extra

route       verb            Authentication      integration
/private    POST/GET        yes                 lambda-private
/private    OPTIONS         no                  lambda-CORS-response

So your pre-flight request will get a nice response and the POST/GET request will hit your desired destination.

These are the integrations (with different lambdas)

And here the Authorizers (only POST has Authorizer)

If you do this, it will attend all OPTIONS regardless of the route (not verified)

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

This is somehow explained here, but they don't say that you need to create 'an extra lambda function' to give a response to that route / verb.

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

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

Until I got to the solution I explored other options. Below are my findings. More than happy to correct the information if someone finds it to be wrong (claims need to be backed up somehow).


Q: I am using a "HTTP API" (AWS). Do I need to switch to "REST API" to resolve this?

A: At some stage I thought so. But no, just follow the instructions above.

However, "REST API" have more options (they are also more costly) and maybe you don't need to do what is described above. If someone has insights about that I'll be happy to update this part. However, having more options may also mean 'more complexity on the setup'.


Q: So what is the CORS configuration on the API for if I need to provide the CORS responses myself?

A: Apparently only for '200 type' responses. -> https://enable-cors.org/server_awsapigateway.html

My functions only work when I provide the CORS response myself.


Q: Can I avoid the pre-fligh OPTIONS request by submitting my data inside a GET instead of a POST

A: NO, it will happen anyway if your request meets the conditions to be a non-simple request.


Q: Why my POST/GET request with Axios within my app/webpage fails complaining about CORS but 'curl' will run just fine.

A: 'curl' Does not care about CORS, the browser does and very much. At least 'curl' allows you to know that 'something is working' but that you have some extra work to get it fully right.

这篇关于Vue&amp;Axios + AWS API网关&Lambda-CORS + POST无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆