web-dev-qa-db-ja.com

AWS API Gateway-CORS + POST動作していません

[〜#〜] cors [〜#〜]は本当に私を夢中にさせており、それを機能させるために何をしようとするのかについて、私は本当にアイデアを失っています。

'abc'と呼ばれる1つのリソースを持つ単純なAPIG APIを作成し、2つのメソッドを追加しました[〜#〜] get [〜#〜]および[〜#〜] post [〜#〜] 両方とも許可付き[〜#〜] none [〜#〜]に設定およびAPIキーが必要falseに設定、すべてが「dev」というステージにデプロイされました。

もちろん、両方のメソッドで[〜#〜] cors [〜#〜]を有効にし、3つのヘッダーAccess-Control-Allow-OriginAccess-Control-Allow-HeadersおよびAccess-Control-Allow-Methodsに追加された[〜#〜] options [〜#〜]メソッドとAccess-Control-Allow-Originに追加された[〜#〜] post [〜#〜]および[〜#〜] get [〜#〜]メソッド。

両方の呼び出しは、「Hello from Lambda」テキストをコンソールに単に出力する同じlambda関数にマッピングされます。

次に、静的Webサイトとしてホストした単純なhtmlページを作成しましたS3Route53を使用してドメインを指定し、jQuery $ .ajax呼び出しを行います。

[〜#〜] get [〜#〜]のみが機能し、期待どおりにテキストをコンソールに出力することを除いて、すべてはドキュメントで説明されているように簡単で簡単で正確に見えます。[〜#〜] post [〜#〜]バージョンでは、次のエラーが発生します。

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.

プリフライトコールは機能し、200 OKを返し、すべてのヘッダーがありますが、POSTコールはそのエラーと400 Bad Requestを返します。

どんな助けも本当に感謝します、AWSチームも見てほしいです...

みんなありがとう。


編集-Google Chromeからコピー:

POST生リクエストヘッダー:

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応答ヘッダー:

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

これは400 Bad Requestを返します

OPTIONS生リクエストヘッダー:

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

オプション生の応答ヘッダー:

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

これは200 OKを返します

17
HBR

OK、問題の原因はAPIGとはまったく無関係であることがわかり、@ AbhignaNagarajaが言ったことを確認して、APIGが適切に構成されていることを確認しました。

問題は実際にjQuery.ajaxを呼び出した方法にあり、contentTypeが 'application/json'の場合にパラメーターをJSON文字列に変換するのに十分賢いと考えました。JSONパラメーターを手動で文字列化する必要があったようです。 JSONを渡してjQueryで文字列化するのではなく、

だから、これは悪い呼び出しです:

$.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);
        }
    });

そして、これは正しい呼び出しです:

 $.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でこのような問題をデバッグする場合のヒントになります。AWSAPIG SDKをダウンロードし、AWSが提供するapigClientを使用して呼び出しを実行し、ヘッダーをカスタムクライアントで取得したヘッダーと比較します。 jQueryおよびapigClientで取得した2セットのヘッダーを調べると、リクエストペイロードが異なって見えることに気付き、フォーマットが間違っていることに気づいたので、400 codeおよびNo 'Access-Control-Allow-Origin'ヘッダーが存在しますすべて理にかなっています。

これがお役に立てば幸いです。

18
HBR

私は同様の問題を抱えていましたが、ラムダプロキシ統合を使用していました。

  • ブラウザを使用してAWS API Gatewayでアクティブ化されたCORS

  • ラムダプロキシ統合がアクティブ化されました

ラムダプロキシ統合を使用する場合、ラムダのコード内からカスタムヘッダーを返すことができます。

        var result = {
        statusCode: data.statusCode | 200,
        headers: {
          "Access-Control-Allow-Origin": "*"
        },
        body: JSON.stringify(responseBody)
    };
    callback(null, result);

これにより、CORSヘッダーが送信されます。ラムダのコード内にCORSを結合せずに、ラムダプロキシ統合で動作させるより良い方法があると思います。ご存知の場合はお知らせください。

12
arseneoaa

API Gatewayでプロキシ統合を使用している場合、API GatewayからCORSを有効にすることはできません。 Lambdaコード自体からヘッダー「Access-Control-Allow-Origin」を設定する必要があります。

doc で言及されています。

Pythonコードサンプル:

    response = {
        'statusCode': 200,
        'headers': {
            'Access-Control-Allow-Origin': '*'
        },
        'body': json.dumps({'message': 'CORS enabled')
    }
    return response
4
Dawn T Cherian

私は同様の問題を抱えていました-APIの設定方法や、フロントエンドで行っていたPOSTリクエストとは何の関係もありませんでした。 AWS API GatewayでのAPIのデプロイ:APIメソッド/リソースを作成し、ラムダ関数に関連付けると、それらは自動デプロイされません。

フロントエンドからこれらのマイクロサービスにアクセスするには、[アクション]をクリックしてから[APIのデプロイ]をクリックする必要があります。

3
Marquistador

これを解決するために、私はあなたにApy GatewayのPost設定の設定を提示します

オプション方式-統合応答-ヘッダーマッピング

X-Requested-With '*'
Access-Control-Allow-Headers 'Content-Type,x-requested-with,Access-Control-Allow-Origin,Access-Control-Allow-Headers,Access-Control-Allow-Methods'
Access-Control-Allow-Origin 'http://localhost:4200'
Access-Control-Allow-Methods 'POST,OPTIONS'

Postメソッド-統合応答-ヘッダーマッピング

Access-Control-Allow-Origin "*" ---> can be changed by your ip obviously

これがお役に立てば幸いです

2
Andres Navarro

ラムダ関数が適切なCORSヘッダーを返し、それらが正しいであることを確認するように指示する多くの投稿がありました。ただし、JSONオブジェクトがJSON.stringify()を使用して文字列化されることもcriticalです。 Postmanがこれを行っているように見えるため、Postmanリクエストと$ .ajaxリクエストが同じjsonオブジェクトを送信するときは誤解を招きます。しかし、1つは成功し、もう1つは失敗します。

0
rickfarina