AWS SAM: в запрошенном ответе ресурса отсутствует заголовок "Access-Control-Allow-Origin"
Я работаю над созданием статического веб-сайта для вызова шлюза API с использованием CORS. У меня есть код ниже, работающий с использованием SAM локально, но я получаю следующую ошибку CORS при попытке вызвать мой API с помощью jQuery с моего статического веб-сайта (размещенного локально):
Failed to load http://localhost:3000/notify: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4000' is therefore not allowed access.
мой template.yaml
:
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Globals:
Api:
# enable CORS; to make more specific, change the origin wildcard
# to a particular domain name, e.g. "'www.example.com'"
Cors: "'*'"
Parameters:
RecaptchaSecret:
Type: String
Resources:
NotifierFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: notifier/build
Handler: app.lambda_handler
Runtime: python3.6
Environment:
Variables:
PARAM1: VALUE
Events:
Notify:
Type: Api
Properties:
Path: /notify
Method: post
Outputs:
NotifierApi:
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/notify/"
NotifierFunction:
Value: !GetAtt NotifierFunction.Arn
NotifierFunctionIamRole:
Value: !GetAtt NotifierFunctionRole.Arn
Мое понимание Globals
раздел в SAM, что он должен применять Api
поле моего (предполагаемого) шлюза API.
Я видел несколько примеров CORS с API-шлюзом в Интернете, где другие использовали стандартные шаблоны API-шлюзов, а некоторые - с использованием SAM в дополнение к файлу чванства, но я не смог увидеть удачный пример того, как кто-то получил CORS для работы с использованием SAM без файла чванства (см. Ссылки ниже). Я чувствую, что, должно быть, мне не хватает чего-то очевидного!
Я использую обычный запрос POST от jQuery, я могу опубликовать свой код переднего плана или "скомпилированный" CloudForamtion, если это будет полезно.
Любая помощь очень ценится!
Ура:)
Ссылки, на которые я смотрел:
Вот мой код функции:
import json
import boto3
import requests
def lambda_handler(event, context):
print "REACHED"
print event
ip = requests.get('http://checkip.amazonaws.com/')
return {
"statusCode": 200,
"headers": {"Access-Control-Allow-Origin": "*"},
"body": json.dumps({
'message': 'hello world',
'location': ip.text.replace('\n', ''),
})
}
0 ответов
Если вас все еще интересует, как этого добиться, это можно сделать непосредственно через шаблон облачной информации, как показано ниже, лучше всего, если вы определите корневой макетный ресурс для начала до вашего дочернего ресурса публикации.
MockMethod:
Type: 'AWS::ApiGateway::Method'
Properties:
AuthorizationType: NONE
RestApiId: STRING
ResourceId: STRING
HttpMethod: OPTIONS
Integration:
Type: MOCK
IntegrationResponses:
- StatusCode: 200
ResponseParameters:
method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'"
method.response.header.Access-Control-Allow-Methods: "'POST,OPTIONS'"
method.response.header.Access-Control-Allow-Origin:* #Note * allows all origins
SelectionPattern: 2\d{2}
ResponseTemplates:
application/json: Empty
PassthroughBehavior: WHEN_NO_MATCH
RequestTemplates:
application/json: '{"statusCode": 200}'
MethodResponses:
- ResponseModels:
application/json: Empty
ResponseParameters:
method.response.header.Access-Control-Allow-Headers: true
method.response.header.Access-Control-Allow-Methods: true
method.response.header.Access-Control-Allow-Origin: true
StatusCode: 200
Обратите внимание: OPTIONS - это то, что обрабатывает ваш предварительный запрос CORS до метода POST. Кроме того, если вы используете AWS_PROXY, как показано ниже, вам необходимо обработать ответ CORS заголовка в вашей лямбда-функции.
POSTmethod:
Type: AWS::ApiGateway::Method
Properties:
HttpMethod: POST
RestApiId: STRING
ResourceId: STRING
Integration:
Type: AWS_PROXY
ConnectionType: INTERNET
IntegrationHttpMethod: POST
Credentials: STRING
Uri: STRING
PassthroughBehavior: WHEN_NO_TEMPLATES
TimeoutInMillis: 10000 #Timeout in 10seconds
MethodResponses:
- StatusCode: 200
ResponseModels:
application/json: Empty
ResponseParameters:
method.response.header.Access-Control-Allow-Headers: true
method.response.header.Access-Control-Allow-Origin: true
- StatusCode: 400
ResponseModels:
application/json: Empty
OPTIONSmethod:
Type: 'AWS::ApiGateway::Method'
Properties:
AuthorizationType: NONE
RestApiId: STRING
ResourceId: STRING
HttpMethod: OPTIONS
Integration:
Type: MOCK
IntegrationResponses:
- StatusCode: 200
ResponseParameters:
method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,x-api-key,X-Amz-Security-Token'"
method.response.header.Access-Control-Allow-Methods: "'POST,OPTIONS'"
method.response.header.Access-Control-Allow-Origin: "'*'"
SelectionPattern: 2\d{2}
ResponseTemplates:
application/json: Empty
PassthroughBehavior: WHEN_NO_MATCH
RequestTemplates:
application/json: '{"statusCode": 200}'
MethodResponses:
- ResponseModels:
application/json: Empty
ResponseParameters:
method.response.header.Access-Control-Allow-Headers: true
method.response.header.Access-Control-Allow-Methods: true
method.response.header.Access-Control-Allow-Origin: true
StatusCode: 200