You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Gatsby集成Mailchimp时遭遇CORS Policy Error,如何解决?

Gatsby集成Mailchimp遭遇CORS错误的解决方案

问题描述

将Mailchimp集成到Gatsby项目时触发CORS政策错误,错误提示:

"has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource."

预期效果:订阅请求成功发送至Mailchimp,用户完成新闻通讯订阅。

相关代码如下:

const SignUpBanner: React.FC<SignUpBannerProps> = ({}: SignUpBannerProps) => {
  const [email, setEmail] = useState('');
  const [subscriptionStatus, setSubscriptionStatus] = useState('');

  const handleSubscribe = async () => {
    try {
      const response = await axios.post(
        'https://xxx.us21.list-manage.com/subscribe/post?u=xxxx&id=xxxx&f_id=xxxx',
        {
          EMAIL: email,
          SIGNUP: 'HOME', // Specify your signup location here
        },
        {
          headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
          },
        }
      );

      if (response.status === 200) {
        setSubscriptionStatus('success');
      } else {
        setSubscriptionStatus('error');
      }
    } catch (error) {
      setSubscriptionStatus('error');
      console.error('Error subscribing:', error);
    }
  };

  return (
    <div className={`${paddingForBanner}`}>
      <div
        className={`${paddingForSignUpContent} d-xl-flex d-lg-flex justify-content-xl-between justify-content-lg-between`}
      >
        <div className={`${signUpHeading}`}>
          Stay connected through our newsletter!
        </div>
        <div className={`${signUptitle}`}>
          Subscribe to our newsletter and get the latest insights on history, art &
          art & culture in your inbox.
          <div className={`${emailInput} d-xl-flex d-lg-flex`}>
            <div className={`${inputDiv}`}>
              <input
                type="email"
                placeholder="Enter Email"
                value={email}
                onChange={(e) => setEmail(e.target.value)}
                className={`${customInputField} ${emailfield} form-control`}
              />
            </div>
            <div
              className={`${signUpButton} d-flex d-lg-flex flex-row flex-lg-row justify-content-end align-items-center justify-content-lg-center `}
              onClick={handleSubscribe}
            >
              <div className={`${signUpText}`}>
                {subscriptionStatus === 'success' ? 'Subscribed!' : 'SIGNUP'}
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
};

export default SignUpBanner;

解决方法

Mailchimp的公开订阅端点不允许浏览器直接发起请求,这是CORS错误的核心原因。以下是三种可行的解决方式:

1. 用Gatsby Serverless Functions做代理

通过Gatsby的Serverless Functions转发请求,绕开浏览器的CORS限制:

  • 在项目根目录创建src/api/subscribe.js文件:
const axios = require('axios');

exports.handler = async (event) => {
  if (event.httpMethod !== 'POST') {
    return { statusCode: 405, body: 'Method Not Allowed' };
  }

  const { email } = JSON.parse(event.body);
  const mailchimpUrl = 'https://xxx.us21.list-manage.com/subscribe/post?u=xxxx&id=xxxx&f_id=xxxx';

  try {
    const response = await axios.post(
      mailchimpUrl,
      new URLSearchParams({
        EMAIL: email,
        SIGNUP: 'HOME'
      }),
      {
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
        }
      }
    );

    return {
      statusCode: response.status,
      body: JSON.stringify({ message: 'Subscription successful' })
    };
  } catch (error) {
    return {
      statusCode: error.response?.status || 500,
      body: JSON.stringify({ error: 'Subscription failed' })
    };
  }
};
  • 修改前端代码中的请求地址为Gatsby函数端点:
const response = await axios.post('/api/subscribe', { email: email });

2. 使用Mailchimp嵌入式表单

直接使用Mailchimp提供的现成订阅表单:

  • 登录Mailchimp后台,进入目标列表的「Signup forms」页面
  • 选择「Embedded forms」,复制生成的HTML代码
  • 在Gatsby组件中通过dangerouslySetInnerHTML嵌入代码,或转换为React组件使用

3. 改用传统表单提交(无AJAX)

放弃AJAX请求,用原生表单提交避免CORS问题:

  • 修改组件的返回部分,用<form>包裹输入框和按钮:
return (
  <div className={`${paddingForBanner}`}>
    <div
      className={`${paddingForSignUpContent} d-xl-flex d-lg-flex justify-content-xl-between justify-content-lg-between`}
    >
      <div className={`${signUpHeading}`}>
        Stay connected through our newsletter!
      </div>
      <div className={`${signUptitle}`}>
        Subscribe to our newsletter and get the latest insights on history, art &
        art & culture in your inbox.
        <form
          action="https://xxx.us21.list-manage.com/subscribe/post?u=xxxx&id=xxxx&f_id=xxxx"
          method="post"
          className={`${emailInput} d-xl-flex d-lg-flex`}
        >
          <div className={`${inputDiv}`}>
            <input
              type="email"
              placeholder="Enter Email"
              name="EMAIL"
              className={`${customInputField} ${emailfield} form-control`}
              required
            />
            <input type="hidden" name="SIGNUP" value="HOME" />
          </div>
          <button
            type="submit"
            className={`${signUpButton} d-flex d-lg-flex flex-row flex-lg-row justify-content-end align-items-center justify-content-lg-center `}
          >
            <div className={`${signUpText}`}>SIGNUP</div>
          </button>
        </form>
      </div>
    </div>
  </div>
);

这种方式会刷新页面,若需要无刷新体验,优先选择第一种代理方案。

内容的提问来源于stack exchange,提问作者Shubham Belwal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 21:05:05