0

I keep getting a 502 error when I do a call to my API point using $http in angular.
The exact error says this:

Failed to load https://xxxxxxxxx.execute-api.eu-west-2.amazonaws.com/dev/api/fund: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. The response had HTTP status code 502.

I have however checked using Postman if that header was in the response and it is:

Access-Control-Allow-Origin →*
Connection →keep-alive
Content-Length →30
Content-Type →application/json
Date →Tue, 03 Jul 2018 10:01:11 GMT
Via →1.1 xxxxxxxxxxxxxxxxxxxxxxxxxxxx.cloudfront.net (CloudFront)

When I do an OPTIONS call to the same URL here is the header of the response using Postman:

Access-Control-Allow-Credentials →false
Access-Control-Allow-Headers →Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent
Access-Control-Allow-Methods →OPTIONS,POST
Access-Control-Allow-Origin →*
Connection →keep-alive
Content-Length →0
Content-Type →application/json
Date →Tue, 03 Jul 2018 10:18:17 GMT
Via →1.1 xxxxxxxxxxxxxxxx.cloudfront.net (CloudFront)
X-Amz-Cf-Id →T_CC-vaqRAoxqnzFZdB9KMI9CAIPQvKAxCat2NPLyaJ5MPpdTVhF1g==
X-Cache →Miss from cloudfront
x-amz-apigw-id →JckIhHWmrPEFcqQ=
x-amzn-RequestId →675517fc-7eaa-11e8-8290-39c903c321e4

Here is the code i have been trying to call the API, pretty straight forward I am really confused on what could be the error:

  $scope.fundAsset = function(assetID, userID){
    $http({
      method: 'POST',
      url: 'https://xxxxxxxxxxx.execute-api.eu-west-2.amazonaws.com/dev/api/fund',
      body: {
        userID: userID,
        assetID: assetID
      }
    }).then(function successCallback(response) {
      console.log(response);
    });
  };
sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
0xtuytuy
  • 1,494
  • 6
  • 26
  • 51

2 Answers2

0

Chrome does not support localhost for CORS requests (an open bug since 2010).

To get around this you can use a domain like lvh.me (which points at 127.0.0.1 just like localhost) or start chrome with the --disable-web-security flag (assuming you're just testing). Also just to be certain, on the server side ensure that you:

  • Allow Access-Control-Expose-Headers: Access-Control-Allow-Origin
  • Access-Control-Allow-Origin: *
  • enable Access to OPTIONS requests as well
Chad Nehemiah
  • 859
  • 6
  • 15
-1

In your Lambda function, make sure that you are returning the Access-Control-Allow-Origin header.

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

To extrapolate this a bit more, this is from my working solution:

serverless.yml

functions:
  ping:
    handler: index.ping
    events:
      - http:
        path: ping 
        method: post
        cors:
          origins:
            - '*'
          headers:
            - Content-Type
            - X-Amz-Date
            - Authorization
            - X-Api-Key
            - X-Amz-Security-Token
          allowCredentials: true

index.js (Lambda Function)

'use strict';

module.exports.ping = (event, context, callback) => {
    const response = {
        statusCode: 200,
        headers: {
                "Access-Control-Allow-Origin" : "*"
              },
        body: JSON.stringify({
            message: 'Pong',
            input: event,
        }),
    };
    callback(null, response);
};

ping.controller.js (AngularJS controller)

$http({
    method: 'POST',
    url: config.apiRoot + '/ping',
    headers: {
        'Content-Type': 'application/json',
    },
    data: JSON.stringify(data)
}).then(
    function successCallback () {
        $scope.feedback = "Ping Success";
    },
    function errorCallback (response) {
        $scope.feedback = "Ping Failed: " + JSON.stringify(response))
    }
);
Matt D
  • 3,289
  • 1
  • 15
  • 29
  • I mean that header needs to be in the response to the POST, i.e. in the response payload from the Lambda function, as well as the OPTIONS. Here is the Serverless Framework explanation of this: https://github.com/serverless/serverless/issues/1955#issuecomment-266235353 – Matt D Jul 03 '18 at 10:37
  • Please have a look above, I did say and I do show that it is, when i do the call with postman i do get the accesscontrolallow origin, but for some reason not when i do it with the browser – 0xtuytuy Jul 03 '18 at 10:40
  • 1
    You say "the header is in the request" not "the header is in the response" – Matt D Jul 03 '18 at 10:43
  • I have added a working solution above, this is an extract of one of my production systems. Hope it helps. – Matt D Jul 03 '18 at 12:51