AWS API网关 - CORS + POST不工作 [英] AWS API Gateway - CORS + POST not working

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

问题描述

CORS 真的让我疯狂,我真的不知道如何尝试让它工作。



我已使用1个资源(名为abc)创建了一个简单的APIG Api,并通过授权设置为 NONE,添加了两个方法 GET POST 和所需的API密钥设置为 false ,一切都部署到名为dev的阶段。



当然,我在两种方法上都启用了 CORS ,并且我看到了访问控制允许原始访问控制允许标头访问控制允许方法添加到选项方法和访问控制允许原因 POST 和 GET 方法。



两个调用都映射到同一个<



然后,我创建了一个简单的html页面,作为静态网站 > S3 ,使用 Route53 指向一个网域,并使用 jQuery $ .ajax 开始测试该API,以进行调用。



看起来很简单,直接,正如在文档中所解释的,除非只有 GET 工作,并按预期将文本输出到控制台。 POST 版本会导致以下错误:



否Access-Control-Allow-报头存在于所请求的资源上。因此,不允许原始http://example.com访问。响应的HTTP状态代码为400.



预检调用正常工作,返回200 OK,所有标头都存在,但是POST调用返回该错误和一个400错误的请求。



请任何帮助非常感谢,我希望AWS团队也在看...



谢谢你们。






EDITED - 从Google Chrome复制:



请求标头:

  POST / dev / urls HTTP / 1.1 
主机:kykul1mshe.execute-api.us-east -1.amazonaws.com
连接:keep-alive
内容长度:73
接受:application / json,text / javascript,* / *; q = 0.01
原产地:http://example.com
User-Agent:Mozilla / 5.0(Macintosh; Intel Mac OS X 10_10_5)AppleWebKit / 537.36(KHTML,类似Gecko)Chrome / 51.0.2704.103 Safari / 537.36
Content-Type:application / json
Referer:http://example.com/dev.html
Accept-Encoding:gzip,deflate,br
Accept-语言:fr-FR,fr; q = 0.8,en-US; q = 0.6,en; q = 0.4


$ b b

POST原始回应标题:

  HTTP / 1.1 400错误请求
日期:Fri,19 Aug 2016 02:14:16 GMT
Content-Type:application / json
Content-Length:177
Connection:keep-alive
x-amzn-RequestId:a1160e45-65b2-11e6 -9766-cd61e49fbcdb
X-Cache:来自cloudfront的错误
Via:1.1 d64756b4df47ce24d6c62b5a8de97e87.cloudfront.net(CloudFront)
X-Amz-Cf-Id:N9mf7apicKbSM_MiZjePbEgZGIFKckWJ3lZljH8iHVKFVTcIIOQuHg ==



这会返回400错误的请求



选项原始请求标题:

 接受:* / * 
Accept-Encoding:gzip,deflate,sdch,br
Accept-Language :fr-FR,fr; q = 0.8,en-US; q = 0.6,en; q = 0.4
访问控制请求标头:accept,content-type
访问控制请求-Method:POST
Connection:keep-alive
Host:kykul1mshe.execute-api.us-east-1.amazonaws.com
原产地:http://example.com
参考:http://example.com/dev.html
User-Agent:Mozilla / 5.0(Macintosh; Intel Mac OS X 10_10_5)AppleWebKit / 537.36(KHTML,like Gecko)Chrome / 51.0.2704.103 Safari / 537.36

OPTIONS原始响应标头:

 访问控制允许标头:Content-Type,X-Amz-Date, ,X-Api-Key,Cache-Control,X-Requested-With 
Access-Control-Allow-Methods:POST,OPTIONS
Access-Control-Allow-Origin:*
Connection: keep-alive
Content-Length:79
Content-Type:application / json
日期:Fri,19 Aug 2016 02:14:16 GMT
Via:1.1 d64756b4df47ce24d6c62b5a8de97e87.cloudfront .net(CloudFront)
X-Amz-Cf-Id:KpGEDmIuf5RHcUnBWuA3oEMZgWHwrjy3SpLuOflRhAD8IIx5vyKGSw ==
x-amzn-RequestId:a10bae11-65b2-11e6-bcf7-63b49c24629e
X-Cache:

这会返回200 OK

方案

好的,我发现问题的根源,这完全与APIG无关,并确认@AbhignaNagaraja提到,我的APIG已正确配置。



这个问题实际上是我调用jQuery.ajax的方式,我认为当contentType是'application / json'时,我可以将我的参数转换为一个JSON字符串。
看起来我不得不手动字符串化JSON参数,而不是传递一个JSON和jQuery stringify。



  $。ajax({
url:myEndpoint,
type:'POST',
crossDomain:true,
data:{
url:$('#url')。val()
},
header:{
X- Api-Key:'blablabla'
},
dataType:'json',
contentType:application / json,
success:function(data){
console.info(data);
}
});

这是正确的电话:

  $ .ajax({
url:myEndpoint,
type:'POST',
crossDomain:true,
data:JSON.stringify ({
url:$('#url')。val()
}),
headers:{
X-Api-Key:'blablabla'
},
dataType:'json',
contentType:application / json,
success:function(data){
console.info(data);
}
});

这是一个提示,如果你正在调试这样的问题CORS:只需下载AWS APIG SDK并尝试使用AWS提供的apigClient执行调用,并将标头与您通过自定义客户端获得的标头进行比较。
当检查我用 jQuery apigClient 得到的两组头文件时,我注意到请求有效负载看起来不同,这是我如何实现格式错误, 400代码无'Access-Control-Allow-Origin'标题是有意义的。



我希望这有助于。


CORS is really driving me crazy and I'm really out of ideas as of what to try to make it work.

I have created a simple APIG Api with 1 resource called 'abc' and added 2 methods GET and POST both with Authorization set to NONE and API Key Required set to false, everything deployed to a stage called 'dev'.

Of course I enabled CORS on both methods and I see the 3 headers Access-Control-Allow-Origin, Access-Control-Allow-Headers and Access-Control-Allow-Methods added to the OPTIONS method and the Access-Control-Allow-Origin added to the POST and GET methods.

Both calls are mapped to the same lambda function that simply outputs a 'Hello from Lambda' text to the console.

Then I have created a simple html page I hosted as a static website on S3, pointed a domain to it using Route53 and started testing the API using jQuery $.ajax to make the calls.

All seems easy, straightforward and exactly as explained in the docs, except only the GET works and outputs the text to the console as expected. The POST version results in the following error:

No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://example.com' is therefore not allowed access. The response had HTTP status code 400.

The preflight call works and returns 200 OK and all headers are there, but the POST call returns that error and a 400 Bad Request.

Please any help is really appreciated, I hope the AWS team is watching too...

Thanks guys.


EDITED - Copied from Google Chrome:

POST Raw Request Headers:

POST /dev/urls HTTP/1.1
Host: kykul1mshe.execute-api.us-east-1.amazonaws.com
Connection: keep-alive
Content-Length: 73
Accept: application/json, text/javascript, */*; q=0.01
Origin: http://example.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36
Content-Type: application/json
Referer: http://example.com/dev.html
Accept-Encoding: gzip, deflate, br
Accept-Language: fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4

POST Raw Response Headers:

HTTP/1.1 400 Bad Request
Date: Fri, 19 Aug 2016 02:14:16 GMT
Content-Type: application/json
Content-Length: 177
Connection: keep-alive
x-amzn-RequestId: a1160e45-65b2-11e6-9766-cd61e49fbcdb
X-Cache: Error from cloudfront
Via: 1.1 d64756b4df47ce24d6c62b5a8de97e87.cloudfront.net (CloudFront)
X-Amz-Cf-Id: N9mf7apicKbSM_MiZjePbEgZGIFKckWJ3lZljH8iHVKFVTcIIOQuHg==

This returns 400 Bad Request

OPTIONS Raw Request Headers:

Accept:*/*
Accept-Encoding:gzip, deflate, sdch, br
Accept-Language:fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
Access-Control-Request-Headers:accept, content-type
Access-Control-Request-Method:POST
Connection:keep-alive
Host:kykul1mshe.execute-api.us-east-1.amazonaws.com
Origin:http://example.com
Referer:http://example.com/dev.html
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36

OPTIONS Raw Response Headers:

Access-Control-Allow-Headers:Content-Type,X-Amz-Date,Authorization,X-Api-Key,Cache-Control,X-Requested-With
Access-Control-Allow-Methods:POST,OPTIONS
Access-Control-Allow-Origin:*
Connection:keep-alive
Content-Length:79
Content-Type:application/json
Date:Fri, 19 Aug 2016 02:14:16 GMT
Via:1.1 d64756b4df47ce24d6c62b5a8de97e87.cloudfront.net (CloudFront)
X-Amz-Cf-Id:KpGEDmIuf5RHcUnBWuA3oEMZgWHwrjy3SpLuOflRhAD8IIx5vyKGSw==
x-amzn-RequestId:a10bae11-65b2-11e6-bcf7-63b49c24629e
X-Cache:Miss from cloudfront

This returns 200 OK

解决方案

Ok, I found the origin of the problem, which happens to be totally unrelated to APIG, and confirms what @AbhignaNagaraja mentioned, that my APIG was properly configured.

The issue is actually in the way I called jQuery.ajax, which I thought was smart enough to convert my parameters to a JSON string when contentType is 'application/json'. It seems I had to manually stringify the JSON params rather than passing a JSON and having jQuery stringify it.

So this is the bad call:

$.ajax({
        url: myEndpoint,
        type: 'POST',
        crossDomain: true,
        data: {
            url: $('#url').val()
        },
        headers: {
            "X-Api-Key": 'blablabla'
        },
        dataType: 'json',
        contentType: "application/json",
        success: function (data) {
            console.info(data);
        }
    });

And this is the right call:

 $.ajax({
        url: myEndpoint,
        type: 'POST',
        crossDomain: true,
        data: JSON.stringify({
            url: $('#url').val()
        }),
        headers: {
            "X-Api-Key": 'blablabla'
        },
        dataType: 'json',
        contentType: "application/json",
        success: function (data) {
            console.info(data);
        }
    });

This can be a hint if you are debugging such an issue with CORS: just download the AWS APIG SDK and try executing the call using the apigClient provided by AWS and compare headers with the ones you get with your custom client. When examining the 2 sets of headers I got with jQuery and apigClient, I noticed the Request Payload looked different and thats how I realized the format was wrong, then the 400 code and the No 'Access-Control-Allow-Origin' header is present all made sense.

I hope this helps.

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

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