将表单从客户端发布到 AWS API 网关功能时如何修复 CORS 错误?
Posted
技术标签:
【中文标题】将表单从客户端发布到 AWS API 网关功能时如何修复 CORS 错误?【英文标题】:How to fix CORS error when posting form from client to AWS API gateway function? 【发布时间】:2019-05-20 10:38:24 【问题描述】:我的前端 React 应用程序上有一个联系表单,我想将其发布到 API 网关后面的 Lambda 函数,而 API 网关又在其顶部有一个自定义域。
我的前端在域 dev.example.com:3000
上运行
我的 API 网关在 contact.example.com
此外,我已经使用无服务器创建了我的 Lambda 函数,并在我的 YAML 文件中启用了 CORS:
# serverless.yml
service: contact-form-api
custom:
secrets: $file(secrets.json)
provider:
name: aws
runtime: nodejs8.10
stage: $self:custom.secrets.NODE_ENV
region: us-east-1
environment:
NODE_ENV: $self:custom.secrets.NODE_ENV
EMAIL: $self:custom.secrets.EMAIL
DOMAIN: $self:custom.secrets.DOMAIN
iamRoleStatements:
- Effect: "Allow"
Action:
- "ses:SendEmail"
Resource: "*"
functions:
send:
handler: handler.send
events:
- http:
path: email/send
method: post
cors: true
我正在使用 AXios 发出发生在客户端的发布请求:
const data = await axios.post(
"https://contact.example.com/email/send",
formData,
"Content-Type": "application/json",
)
我得到的错误是:
从源“http://dev.example.com:3000”访问“https://contact.example.com/email/send”处的 XMLHttpRequest 已被 CORS 策略阻止:“Access-Control-Allow-Origin”标头包含无效值“example.com”。
我原以为将前端和 API 放在同一个域中可以在本地解决任何 cors 错误(尽管我在本地欺骗 dev.example.com
)以便进行测试)。我还认为我的 YAML 文件中的 cors 设置会绕过它。
有人知道为什么我仍然会收到此 CORS 错误吗?
编辑:显示在 Lambda 函数中运行的处理程序代码 // handler.js
const aws = require('aws-sdk')
const ses = new aws.SES()
const myEmail = process.env.EMAIL
const myDomain = process.env.DOMAIN
function generateResponse (code, payload)
return
statusCode: code,
headers:
'Access-Control-Allow-Origin': "*",
'Access-Control-Allow-Headers': 'x-requested-with',
'Access-Control-Allow-Credentials': true
,
body: JSON.stringify(payload)
function generateError (code, err)
console.log(err)
return
statusCode: code,
headers:
'Access-Control-Allow-Origin': "*",
'Access-Control-Allow-Headers': 'x-requested-with',
'Access-Control-Allow-Credentials': true
,
body: JSON.stringify(err.message)
function generateEmailParams (body)
const email, name, content = JSON.parse(body)
console.log(email, name, content)
if (!(email && name && content))
throw new Error('Missing parameters! Make sure to add parameters \'email\', \'name\', \'content\'.')
return
Source: myEmail,
Destination: ToAddresses: [myEmail] ,
ReplyToAddresses: [email],
Message:
Body:
Text:
Charset: 'UTF-8',
Data: `Message sent from email $email by $name \nContent: $content`
,
Subject:
Charset: 'UTF-8',
Data: `You received a message from $myDomain!`
module.exports.send = async (event) =>
try
const emailParams = generateEmailParams(event.body)
const data = await ses.sendEmail(emailParams).promise()
return generateResponse(200, data)
catch (err)
return generateError(500, err)
【问题讨论】:
因为'Access-Control-Allow-Origin'
标头的值应该是*
或http://dev.example.com:3000
...即协议和端口需要匹配源
你的意思是axios post请求中的header吗?
抱歉,我认为很明显我在谈论 'Access-Control-Allow-Origin'
标头 -
我只是想仔细检查一下,因为我确实尝试了您的建议,但无济于事。我尝试同时设置 "Access-Control-Allow-Origin": "dev.example.com:3000"
和 "Access-Control-Allow-Origin": "*"
但仍然遇到相同的 CORS 错误
a) 我说的是http://dev.example.com:3000
而不是dev.example.com:3000
并且b) 我看不到你在做任何事情,所以也许你做错了(在浏览器中查看您实际上是从服务器获取的标头)
【参考方案1】:
您应该将 HTTP 请求标头添加为“内容类型”:
现在,转到集成请求,并将映射模板更改如下:
希望,它会有所帮助。并且不要忘记在测试之前部署 API。
【讨论】:
以上是关于将表单从客户端发布到 AWS API 网关功能时如何修复 CORS 错误?的主要内容,如果未能解决你的问题,请参考以下文章
使用 REST 客户端 POSTMAN 使用 api 密钥调用 AWS api 网关端点
Terraform 不会将 step 功能部署到 API 网关
AWS:使用 cloudformation 模板将 WAF 附加到 api 网关