发出 OPTIONS 请求时 AWS API 网关错误
AWS API gateway error while making OPTIONS request
我正在使用 CFT 为我的 API 创建环境。我已经为 CORS 添加了选项。我注意到当我从 AWS console for OPTIONS
进行测试时,我得到了 200
的响应。但是,当我从 CURL or PostMan
执行相同操作时,我收到 500
内部服务器错误。在审查了与之相关的SO问题之后。我已将集成响应修改为 CONVERT_TO_TEXT。但这也没有解决问题。
我注意到日志中有一个有线行为。以下是来自 AWS 控制台的请求的日志片段:
Sat Apr 13 15:06:26 UTC 2019 : Method request headers: { Access-Control-Request-Method= POST, Content-Type= application/json}
Sat Apr 13 15:06:26 UTC 2019 : Method request body before transformations:
Sat Apr 13 15:06:26 UTC 2019 : Method response body after transformations:
Sat Apr 13 15:06:26 UTC 2019 : Method response headers: {X-Requested-With=*, Access-Control-Allow-Headers=Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-requested-with, Access-Control-Allow-Origin=*, Access-Control-Allow-Methods=POST,OPTIONS, Content-Type=application/json}
Sat Apr 13 15:06:26 UTC 2019 : Successfully completed execution
Sat Apr 13 15:06:26 UTC 2019 : Method completed with status: 200
但是当我从 CRUL 或 PM 发出相同的请求时,我看到了以下日志:
Method request path: {}
Method request query string: {}
Method request headers: Method request headers: {Accept=*/*, CloudFront-Viewer-Country=IN, CloudFront-Forwarded-Proto=https, CloudFront-Is-Tablet-Viewer=false, CloudFront-Is-Mobile-Viewer=false, User-Agent=curl/7.55.1, X-Forwarded-Proto=https, CloudFront-Is-SmartTV-Viewer=false, Host=MYHOST, X-Forwarded-Port=443, (CloudFront), Access-Control-Request-Method=POST, CloudFront-Is-Desktop-Viewer=true, Content-Type=application/json}
Method request body before transformations: [Binary Data]
Execution failed due to configuration error: Unable to transform request
Method completed with status: 500
我们可以看到它正在尝试转换 [Binary Data]
但我没有发送任何东西。
我使用的卷曲:curl -X OPTIONS -H "Access-Control-Request-Headers: Content-Type" -H "Access-Control-Request-Method: POST" -H "Access-Control-Allow-Origin: '*'" -v MYHOST
为什么我在日志中看到这种差异?我的配置出了什么问题?你能帮帮我吗
更新:我正在使用下面的 CFT
Type: AWS::ApiGateway::Method
Properties:
AuthorizationType: NONE
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: "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'"
method.response.header.Access-Control-Allow-Origin: "'*'"
RequestTemplates:
application/json:
Fn::Join:
- ''
- - "{"
- ' {"statusCode":200} '
- "}"
MethodResponses:
- StatusCode: 200
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
将 contentHandling: CONVERT_TO_TEXT
参数添加到集成请求和集成响应设置中的记录要求较少。
大摇大摆的 CORS 配置看起来像这样:
responses: {
200: {
description: "Returning CORS headers",
headers: {
"Access-Control-Allow-Headers":{ type: "string" },
"Access-Control-Allow-Methods": { type: "string" },
"Access-Control-Allow-Origin": { type: "string" },
}
}
},
"x-amazon-apigateway-integration": {
type: "mock",
contentHandling: "CONVERT_TO_TEXT", // Resolves problems with cloudfront binary content issues
requestTemplates: {
"application/json": "{ \"statusCode\": 200 }"
},
responses: {
"default": {
statusCode: "200",
contentHandling: "CONVERT_TO_TEXT", // Resolves problems with cloudfront binary content issues
responseParameters: {
"method.response.header.Access-Control-Allow-Headers": "'*'",
"method.response.header.Access-Control-Allow-Methods" : "'*'",
"method.response.header.Access-Control-Allow-Origin" : "'*'"
},
responseTemplates: {
"application/json": "{}"
}
}
}
}
如果在您的 API 网关设置中您已将 'application/json' 添加到二进制媒体类型(例如您想要 gzip 响应)或者如果此请求无论如何都是针对二进制媒体类型的,则'enable CORS' 功能添加的默认选项需要调整。
如上所说,您至少需要将 contentHandling 设置为“CONVERT_TO_TEXT”才能进行集成。对我来说,它无需将其添加到集成响应中即可工作。您可以通过 AWS CLI 执行此操作,如下所示:
aws apigateway update-integration --rest-api-id YOUR_REST_ID --resource-id YOUR_RESOURCE_ID --http-method OPTIONS --patch-operations op='replace',path='/contentHandling',value='CONVERT_TO_TEXT'
哦,别忘了之后重新部署 API。
对我来说,问题出在这一行:
"x-amazon-apigateway-binary-media-types" : [ "multipart/form-data", "application/zip", "*/*" ]
只需删除 "*/*"
"x-amazon-apigateway-binary-media-types" : [ "multipart/form-data", "application/zip" ]
才发现这个才看到@bgw的评论
无论如何,希望这可以帮助其他不搜索小时数的人!
我正在使用 CFT 为我的 API 创建环境。我已经为 CORS 添加了选项。我注意到当我从 AWS console for OPTIONS
进行测试时,我得到了 200
的响应。但是,当我从 CURL or PostMan
执行相同操作时,我收到 500
内部服务器错误。在审查了与之相关的SO问题之后。我已将集成响应修改为 CONVERT_TO_TEXT。但这也没有解决问题。
我注意到日志中有一个有线行为。以下是来自 AWS 控制台的请求的日志片段:
Sat Apr 13 15:06:26 UTC 2019 : Method request headers: { Access-Control-Request-Method= POST, Content-Type= application/json}
Sat Apr 13 15:06:26 UTC 2019 : Method request body before transformations:
Sat Apr 13 15:06:26 UTC 2019 : Method response body after transformations:
Sat Apr 13 15:06:26 UTC 2019 : Method response headers: {X-Requested-With=*, Access-Control-Allow-Headers=Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-requested-with, Access-Control-Allow-Origin=*, Access-Control-Allow-Methods=POST,OPTIONS, Content-Type=application/json}
Sat Apr 13 15:06:26 UTC 2019 : Successfully completed execution
Sat Apr 13 15:06:26 UTC 2019 : Method completed with status: 200
但是当我从 CRUL 或 PM 发出相同的请求时,我看到了以下日志:
Method request path: {}
Method request query string: {}
Method request headers: Method request headers: {Accept=*/*, CloudFront-Viewer-Country=IN, CloudFront-Forwarded-Proto=https, CloudFront-Is-Tablet-Viewer=false, CloudFront-Is-Mobile-Viewer=false, User-Agent=curl/7.55.1, X-Forwarded-Proto=https, CloudFront-Is-SmartTV-Viewer=false, Host=MYHOST, X-Forwarded-Port=443, (CloudFront), Access-Control-Request-Method=POST, CloudFront-Is-Desktop-Viewer=true, Content-Type=application/json}
Method request body before transformations: [Binary Data]
Execution failed due to configuration error: Unable to transform request
Method completed with status: 500
我们可以看到它正在尝试转换 [Binary Data]
但我没有发送任何东西。
我使用的卷曲:curl -X OPTIONS -H "Access-Control-Request-Headers: Content-Type" -H "Access-Control-Request-Method: POST" -H "Access-Control-Allow-Origin: '*'" -v MYHOST
为什么我在日志中看到这种差异?我的配置出了什么问题?你能帮帮我吗
更新:我正在使用下面的 CFT
Type: AWS::ApiGateway::Method
Properties:
AuthorizationType: NONE
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: "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'"
method.response.header.Access-Control-Allow-Origin: "'*'"
RequestTemplates:
application/json:
Fn::Join:
- ''
- - "{"
- ' {"statusCode":200} '
- "}"
MethodResponses:
- StatusCode: 200
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
将 contentHandling: CONVERT_TO_TEXT
参数添加到集成请求和集成响应设置中的记录要求较少。
大摇大摆的 CORS 配置看起来像这样:
responses: {
200: {
description: "Returning CORS headers",
headers: {
"Access-Control-Allow-Headers":{ type: "string" },
"Access-Control-Allow-Methods": { type: "string" },
"Access-Control-Allow-Origin": { type: "string" },
}
}
},
"x-amazon-apigateway-integration": {
type: "mock",
contentHandling: "CONVERT_TO_TEXT", // Resolves problems with cloudfront binary content issues
requestTemplates: {
"application/json": "{ \"statusCode\": 200 }"
},
responses: {
"default": {
statusCode: "200",
contentHandling: "CONVERT_TO_TEXT", // Resolves problems with cloudfront binary content issues
responseParameters: {
"method.response.header.Access-Control-Allow-Headers": "'*'",
"method.response.header.Access-Control-Allow-Methods" : "'*'",
"method.response.header.Access-Control-Allow-Origin" : "'*'"
},
responseTemplates: {
"application/json": "{}"
}
}
}
}
如果在您的 API 网关设置中您已将 'application/json' 添加到二进制媒体类型(例如您想要 gzip 响应)或者如果此请求无论如何都是针对二进制媒体类型的,则'enable CORS' 功能添加的默认选项需要调整。
如上所说,您至少需要将 contentHandling 设置为“CONVERT_TO_TEXT”才能进行集成。对我来说,它无需将其添加到集成响应中即可工作。您可以通过 AWS CLI 执行此操作,如下所示:
aws apigateway update-integration --rest-api-id YOUR_REST_ID --resource-id YOUR_RESOURCE_ID --http-method OPTIONS --patch-operations op='replace',path='/contentHandling',value='CONVERT_TO_TEXT'
哦,别忘了之后重新部署 API。
对我来说,问题出在这一行:
"x-amazon-apigateway-binary-media-types" : [ "multipart/form-data", "application/zip", "*/*" ]
只需删除 "*/*"
"x-amazon-apigateway-binary-media-types" : [ "multipart/form-data", "application/zip" ]
才发现这个才看到@bgw的评论
无论如何,希望这可以帮助其他不搜索小时数的人!