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

Next.js/React调用Pinterest API遇CORS拦截,已加白名单仍无效

Pinterest OAuth Token 请求遇CORS问题排查(已添加白名单仍报错)

问题详情

你在Next.js/React应用中调用Pinterest API获取授权Token时遇到CORS错误,相关代码如下:

const redirectUrl = 'http://localhost:3000/pinterest';
const clientId = '1234';
const clientSecret = 'XXXXXXXXXXX';

let url = 'https://api.pinterest.com/v5/oauth/token';
let body = {
    'code': code,
    'grant_type': 'authorization_code',
    'redirect_uri': redirectUrl
};

let accessTokenRequestBody = Object.keys(body)
    .map((k) => `${encodeURIComponent(k)}=${encodeURIComponent(body[k])}`)
    .join('&');

const clientIdAndSecretBase64 = Buffer.from(`${clientId}:${clientSecret}`).toString('base64');

try {
    let response = await axios.post(url, accessTokenRequestBody, {
        "headers": {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Authorization': `Basic ${clientIdAndSecretBase64}`
        }
    })
    console.log(response)
} catch (e) {
    console.log("error")
    console.log(e?.reponse?.data)
}

错误信息:

从源'http://localhost:3000'访问'https://api.pinterest.com/v5/oauth/token'的XMLHttpRequest被CORS策略阻止:预检请求的响应未通过访问控制检查:请求的资源上不存在'Access-Control-Allow-Origin'标头。

你已将localhost:3000和localhost:3000/pinterest添加到Pinterest应用白名单,但问题依旧,以下是可能的原因及解决办法:


可能的原因及解决办法

1. Token接口本身禁止前端直接调用

Pinterest的/v5/oauth/token接口是专门给后端服务设计的,不允许前端浏览器直接请求。因为这个接口需要用到client_secret,如果在前端暴露这个密钥,会导致你的应用权限被恶意滥用,所以Pinterest不会给这个接口配置CORS允许头,无论你加多少白名单都没用。

2. 白名单配置的是授权回调地址,不是API请求源

你在Pinterest后台添加的域名是OAuth授权流程的回调地址——也就是用户授权后Pinterest跳转回你应用的地址,和API请求的CORS白名单完全是两回事。Pinterest的API接口(包括Token接口)并不支持配置前端请求源的CORS白名单。

3. 正确解决方式:用Next.js API路由做代理

把请求逻辑移到Next.js的后端API路由里,前端调用自己的后端接口,再由后端转发请求到Pinterest,这样就绕开了浏览器的CORS限制:

示例代码(Pages Router)

创建pages/api/pinterest-token.js:

import axios from 'axios';

export default async function handler(req, res) {
  if (req.method !== 'POST') {
    return res.status(405).json({ message: '仅支持POST请求' });
  }

  const { code } = req.body;
  const redirectUrl = 'http://localhost:3000/pinterest';
  const clientId = '1234';
  const clientSecret = 'XXXXXXXXXXX'; // 这里的密钥只会在后端暴露,安全

  const url = 'https://api.pinterest.com/v5/oauth/token';
  const body = {
    code,
    grant_type: 'authorization_code',
    redirect_uri: redirectUrl
  };

  const accessTokenRequestBody = Object.keys(body)
    .map((k) => `${encodeURIComponent(k)}=${encodeURIComponent(body[k])}`)
    .join('&');

  const clientIdAndSecretBase64 = Buffer.from(`${clientId}:${clientSecret}`).toString('base64');

  try {
    const response = await axios.post(url, accessTokenRequestBody, {
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Authorization': `Basic ${clientIdAndSecretBase64}`
      }
    });
    res.status(200).json(response.data);
  } catch (e) {
    res.status(e.response?.status || 500).json(e.response?.data || { message: '请求失败' });
  }
}

前端调用修改

try {
  const response = await axios.post('/api/pinterest-token', { code });
  console.log('获取到的Token:', response.data);
} catch (e) {
  console.error('获取Token失败:', e);
}

4. 额外注意事项

  • 绝对不要在前端代码里写clientSecret,避免密钥泄露。
  • 生产环境部署时,记得把redirectUrl改成你的生产域名,同时在Pinterest后台更新回调地址配置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 10:05:30