我在尝试从 Netlify 上托管的静态生成的 Nuxt.js 站点向处理 Mailchimp API 请求的无服务器函数发出请求时遇到 CORS(跨源资源共享)问题。设置无服务器功能是为了让用户订阅 Mailchimp 列表。
我能够使用
Netlify CLI
成功调用该函数,但是当请求客户端(本地和产品中)时,该函数返回以下内容:
Access to XMLHttpRequest at 'https://us11.api.mailchimp.com/.netlify/functions/mailchimp/mailchimp' from origin 'https://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
我在无服务器函数和
netlify.toml
中设置标头以允许跨源请求,但正如您在错误中看到的那样,我似乎直接访问Mailchimp API而不是代理端点,所以我想知道是否我误解了无服务器函数的方法,或者错过了导致错误的过程中的步骤?
参见下面的代码:
netlify.toml
[dev]
command = "yarn dev"
targetPort = 3000
[build]
command = "yarn generate"
publish = "dist"
functions = "functions/"
[[headers]]
# Define which paths this specific [[headers]] block will cover.
for = "/*"
[headers.values]
Access-Control-Allow-Origin = "*"
表单组件
...
methods: {
async subscribe() {
try {
const response = await this.$axios.$post(
"/.netlify/functions/mailchimp/mailchimp",
{ email: this.email }
);
console.log(response); // You can handle success message or redirect here
} catch (error) {
console.error("Failed to subscribe:", error);
// Handle error (e.g., show error message)
}
},
}
无服务器功能
// Path: /functions/mailchimp/mailchimp
const mailchimp = require("@mailchimp/mailchimp_marketing");
mailchimp.setConfig({
apiKey: process.env.MAILCHIMP_API_KEY,
server: process.env.MAILCHIMP_SERVER,
});
const headers = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Allow-Methods': 'POST',
};
exports.handler = async (event) => {
if (event.httpMethod !== 'POST') {
return {
statusCode: 405,
body: 'Method Not Allowed',
headers: { 'Allow': 'POST' }
}
}
const data = JSON.parse(event.body)
console.log(data);
if (!data.email) {
return { statusCode: 422, body: 'email is required.' }
}
const mailchimpData = {
email_address: data.email,
status: "subscribed",
skip_merge_validation: true,
}
try {
await mailchimp.lists.addListMember(process.env.MAILCHIMP_LIST_ID, mailchimpData)
return {
statusCode: 200,
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Allow-Methods': 'POST',
},
body: 'Your message was sent successfully!'
}
} catch (error) {
return {
statusCode: 422,
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Allow-Methods': 'POST',
},
body: `Error: ${error}`
}
}
}
任何成功集成无服务器功能的见解、建议或替代方法都将不胜感激。谢谢!
您遇到的 CORS 错误是由于无服务器函数绕过 Nuxt.js 代理直接调用 Mailchimp API 造成的。要解决此问题,需要通过 Nuxt.js 代理发出 Mailchimp 请求。
替换Serverless功能:
const mailchimp = require("@mailchimp/mailchimp_marketing");
mailchimp.setConfig({
apiKey: process.env.MAILCHIMP_API_KEY,
server: process.env.MAILCHIMP_SERVER,
});
const headers = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Allow-Methods': 'POST',
};
const proxyMailchimpUrl = process.env.NUXT_PROXY_URL + '/mailchimp'; // Assuming Nuxt.js proxy is configured to route '/mailchimp' to the Mailchimp API
exports.handler = async (event) =>
{
if (event.httpMethod !== 'POST') {
return {
statusCode: 405,
body: 'Method Not Allowed',
headers: { 'Allow': 'POST' }
}
}
const data = JSON.parse(event.body);
if (!data.email) {
return { statusCode: 422, body: 'email is required.' };
}
const mailchimpData = {
email_address: data.email,
status: 'subscribed',
skip_merge_validation: true,
};
try {
const response = await axios.post(proxyMailchimpUrl, mailchimpData);
console.log(response.data);
return {
statusCode: 200,
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Allow-Methods': 'POST',
},
body: 'Your message was sent successfully!'
}
} catch (error) {
console.error('Failed to subscribe:', error);
return {
statusCode: 422,
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Allow-Methods': 'POST',
},
body: `Error: ${error}`
}
}
};
此修改后的无服务器函数将通过 Nuxt.js 代理代理 Mailchimp 请求,确保正确设置 CORS 标头,并通过 Nuxt.js 代理将请求路由到 Mailchimp API。