2016-08-17 5 views
7

CORS действительно сводит меня с ума, и я действительно не в курсе, как пытаться заставить его работать.AWS API Gateway - CORS + POST не работает

Я создал простой APIG Апи с 1 ресурс под названием 'ABC' и добавил 2 метода GET и POST как с Authorization набор для NONE и API Key Требуется набор для ложной , все развернуто до стадии под названием «dev».

Конечно, я позволил Корс на обоих методах, и я вижу 3 разъема Access-Control-Allow-Origin, Access-Control-Allow-Headers и Access-Control-Allow-методы добавил к ВАРИАНТАМ метод и Access-Control-Allow-Origin добавлены в POST и GET методы.

Оба вызова отображаются на одну и ту же функцию lambda, которая просто выводит текст «Hello from Lambda» на консоль.

Тогда я создал простую HTML-страницу я провел как статический сайт на S3, указал домен к нему с помощью Route53 и начал тестирование API с помощью 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 наблюдает тоже ...

Спасибо, ребята.


EDITED - скопировано из 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 Сырого 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== 

Это возвращает 400 Bad Request

ВАРИАНТЫ Сырые Заголовки запросов:

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 

Это возвращает 200 OK

+0

Привет, я из ави шлюза. Я не вижу ничего плохого в том, как вы настраиваете свой api. Не могли бы вы обновить необработанные запросы? Это поможет в отладке. –

+0

Спасибо за ответ @AbhignaNagaraja - я обновил сообщение заголовками, которые я получил в Google Chrome (я только что скрыл реальное доменное имя). – HBR

ответ

8

Ok, я нашел источник проблемы, которая случается быть совершенно не связан с APIG, и подтверждает, что @AbhignaNagaraja упомянул, что мой APIG был правильно настроен.

Проблема в том, что я назвал jQuery.ajax, который, как я думал, достаточно умен, чтобы преобразовать мои параметры в строку JSON, когда contentType - это «application/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: просто скачать AWS APIG SDK и попробуйте выполнить вызов, используя apigClient, предоставленный AWS, и сравните заголовки с теми, которые вы получаете с вашим пользовательским клиентом. При рассмотрении 2 набора заголовков, которые я получил с JQuery и apigClient, я заметил, что запрос Payload выглядел иначе и то, как я понял, что формат был не прав, то 400 кода и в Нет «Access-Control -Allow-Origin ' header есть все принятый смысл.

Надеюсь, это поможет.

+0

1 млн. Upvotes !!! – inspired

+0

* «Кажется, мне пришлось вручную подстроить параметры JSON, а не передавать JSON и связать его с jQuery.»: * Если бы это был json, jquery не понадобилось бы его строчить. То, что вы * * проходило, было объектом, а не json, а jquery преобразует все, что не является строкой в ​​строку (param string). Соединив его, вы превратили его в строку, и, таким образом, jquery не коснулся его. –

+0

Спасибо, стягивание разрешило ту же проблему для меня. – deanmau5

2

У меня была аналогичная проблема - и это не имело ничего общего с тем, как был настроен API, или запросом POST, который я делал в интерфейсе. Для меня проблема заключалась в развертывании API на AWS API Gateway. Когда вы создаете метод/ресурс API и привязываете их к лямбда-функции, они не развертываются автоматически.

Вы должны нажать «Действия», а затем «Развернуть API», чтобы получить доступ к этим микросервисам из интерфейса.

4

У меня была аналогичная проблема, но с лямбда-прокси интеграции:

  • CORS активированные на AWS API шлюза с помощью браузера

  • лямбда-прокси Интеграция активированную

Когда используя интеграцию лямбда-прокси, вы можете вернуть пользовательские заголовки из кода лямбда:

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

Таким образом вы получаете отправленный заголовок CORS. Я думаю, что может быть лучший способ заставить его работать с интеграцией лямбда-прокси, не связывая CORS внутри кода лямбда, пожалуйста, дайте мне знать, если вы знаете.

0

Было много сообщений, которые направляют вас на то, чтобы убедиться, что функция лямбда возвращает соответствующие заголовки CORS, и они верны. Тем не менее, также критический, что объект json стробируется с использованием JSON.stringify(). Кажется, что Почтальон делает это для нас, поэтому он вводит в заблуждение, когда запрос Postman и запрос $ .ajax отправляют один и тот же объект json; но один преуспевает, и один терпит неудачу.