如何通过 Google 标签管理器中的 JavaScript 发送 MailChimp API 请求?

How can I send a MailChimp API request via JavaScript in Google Tag Manager?

我正在尝试使用 MailChimp API v3.0 从 Google 标签管理器更新 MailChimp 成员,但我遇到了问题。这是我的代码,我 运行 来自真实域(不是本地主机),使用有效的 SSL 证书保护(如果重要的话)。

const xmlHttp = new XMLHttpRequest();

xmlHttp.onreadystatechange = () => {
    try {
        if (xmlHttp.readyState !== 4) return;
        if (xmlHttp.status !== 200)
            throw new Error(
                xmlHttp.statusText || 'HTTP STATUS ' + xmlHttp.status
            );
        console.log(xmlHttp.responseText);
    } catch (err) {
        console.error(err);
    }
};

xmlHttp.open('POST', 'https://us12.api.mailchimp.com/3.0/lists/d5bed898ae/members/0740287eb1c63371a10d32ebf58391f9');
xmlHttp.setRequestHeader('Authorization', 'Basic ' + btoa('anystring' + ':' + 'my-api-key-here'));
xmlHttp.setRequestHeader('content-type', 'application/json');
xmlHttp.send('{"email_address":"user@example.com", "status":"subscribed", "member_rating":"4"}');

我收到 CORS 错误:

Access to XMLHttpRequest at 'https://us12.api.mailchimp.com/3.0/lists/d5bed898ae/members/0740287eb1c63371a10d32ebf58391f9' from origin 'https://subdomain.example.com' 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.

我做错了什么?

更新:

请注意,我不是要添加新成员,而是要更新现有成员。此外,API 键不可见,我将其作为 GTM 变量获取。此外,代码在域上 运行ning,因为页面上加载了 GTM。

我应该在哪里 运行 此代码?在 Mailchimp 服务器上?我错过了什么?

首先,EEK!你应该 永远不要 在 client-facing 代码中放置私有 API 密钥,在本例中是在 GTM 中。如果网站访问者注意到,他们可以轻松地使用您的 API 密钥自己对您的 Mailchimp 帐户执行几乎所有他们想做的事情,包括删除其中的所有内容。 From Mailchimp's docs:

API keys grant full access to your Mailchimp account and should be protected the same way you would protect your password.

如果您已经将此代码投入使用,即使只是几分钟,您也会想要立即 disable/revoke 那个 API 键并创建一个新的。


其次,CORS 错误是因为 MailChimp 特别不支持 API 来自其域外浏览器的请求 - 例如Cross-Origin 需要正确 CORS 响应的请求 header。原因与我上面的警告相同 - 由于固有的安全风险,您不应该从 client-side 代码进行 API 调用。在同一个 MailChimp 文档页面上,他们重复了这个警告:

Because of the potential security risks associated with exposing account API keys, Mailchimp does not support client-side implementation of our API using CORS requests or including API keys in mobile apps.

有关类似的讨论,请参阅此 Whosebug question


要解决这个问题,您需要让实际的 API 调用来自实际的 server-side 代码。大多数人可能会通过他们自己的站点代理请求 - 因此,如果您的站点是 example.com,您可能会让 GTM 对 example.com/mailchimp-proxy.php?action=update&list=d5bed898ae&user=0740287eb1c63371a10d32ebf58391f9&info=... 进行 AJAX 调用,然后调用 PHP 脚本反过来会用数据调用 https://us12.api.mailchimp.com/3.0/... 的实际 API 端点。因为密码是 运行ning server-side,如果你把你的钥匙放在里面,应该没有人能读到它。

另一种方法是使用 Zapier 或 "serverless" 函数来代理请求,这样您就不需要 运行 您自己的服务器。