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

调用Deezer API遇CORS错误:单请求正常双请求失败如何解决?

问题描述

在React项目中自定义useFetch Hook,使用axios的Promise.all同时发起两个Deezer API请求时触发CORS错误,但仅发起单个请求时可正常获取数据,Postman测试接口能成功得到响应。

错误提示:

Access to XMLHttpRequest at 'https://api.deezer.com/artist/145/top?limit=10' from origin 'http://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.

自定义useFetch Hook代码:

export const useFetch = (url, url2) => {
  const [isLoading, setIsloading] = useState(false);
  const [apiData, setApiData] = useState(null);
  const [isError, setIsError] = useState(null);


useEffect(() => {
    setIsloading(true);
    const allPromise = Promise.all([
      axios.get(url, {
        headers: {
          "X-RapidAPI-Key": process.env.REACT_APP_API_KEY,
          "X-RapidAPI-Host": process.env.REACT_API_HOST,
          "Access-Control-Allow-Origin": "https://localhost:3000/",
        },
        mode: "cors",
      }),
      axios.get(url2, {
        headers: {
          "X-RapidAPI-Key": process.env.REACT_APP_API_KEY,
          "X-RapidAPI-Host": process.env.REACT_API_HOST,
          "Access-Control-Allow-Origin": "https://localhost:3000/",
        },
        mode: "cors",
      }),
    ]);

    try {
      const values = allPromise;
      console.log(values); // [resolvedValue1, resolvedValue2]
      setApiData(values);
    } catch (error) {
      console.log(error); // rejectReason of any first rejected promise
    }
  }, [url]);
  return { isLoading, apiData, isError };
};

组件调用代码:

const SongList = () => {
  const { isLoading, apiData, isError } = useFetch(
    process.env.REACT_APP_API_URL_PLAYLIST,
process.env.REACT_APP_API_URL
  );
  console.log(apiData);
}
问题原因
  1. 请求头配置错误:你在请求中添加了Access-Control-Allow-Origin头,这个头是服务器返回给浏览器的响应头,不是前端请求时需要发送的。前端发送这个多余的头会触发浏览器的预检OPTIONS请求,而Deezer API服务器未处理该预检请求,直接导致CORS报错。
  2. Promise异步处理错误:Promise.all返回的是Promise对象,你直接将其赋值给values,没有等待异步请求完成,不仅无法拿到实际响应数据,try/catch也无法正确捕获请求错误。
  3. useEffect依赖缺失:useEffect的依赖数组仅包含url,但Hook逻辑中用到了url2,当url2变化时不会触发重新请求,还可能导致请求逻辑异常。
  4. 并发预检请求限制:部分API对并发的预检请求有频率限制,同时发起两个请求会触发两次预检,可能被服务器判定为异常请求而拒绝。
解决方法

1. 修正请求头配置

移除请求中的Access-Control-Allow-Origin头和多余的mode: "cors"(axios默认采用cors模式),正确的请求配置如下:

axios.get(url, {
  headers: {
    "X-RapidAPI-Key": process.env.REACT_APP_API_KEY,
    "X-RapidAPI-Host": process.env.REACT_APP_API_HOST,
  },
})

2. 正确处理Promise异步逻辑

使用async/await配合try/catch/finally处理异步请求,确保能正确获取数据、捕获错误,并在请求结束后更新加载状态:

useEffect(() => {
  const fetchData = async () => {
    setIsloading(true);
    try {
      const [res1, res2] = await Promise.all([
        axios.get(url, {
          headers: {
            "X-RapidAPI-Key": process.env.REACT_APP_API_KEY,
            "X-RapidAPI-Host": process.env.REACT_APP_API_HOST,
          },
        }),
        axios.get(url2, {
          headers: {
            "X-RapidAPI-Key": process.env.REACT_APP_API_KEY,
            "X-RapidAPI-Host": process.env.REACT_APP_API_HOST,
          },
        }),
      ]);
      setApiData([res1.data, res2.data]); // 存储实际响应数据
      setIsError(null);
    } catch (error) {
      setIsError(error);
      console.error("请求失败:", error);
    } finally {
      setIsloading(false); // 请求结束后无论成败都关闭加载状态
    }
  };

  fetchData();
}, [url, url2]); // 添加url2到依赖数组,确保参数变化时重新请求

3. 代理解决CORS问题(终极方案)

如果修正请求后仍出现CORS错误,说明Deezer API本身不允许前端直接跨域请求,此时需要使用代理:

  • React内置代理:在package.json中添加"proxy": "https://api.deezer.com",前端请求时使用相对路径,比如axios.get("/artist/145/top?limit=10")
  • 自定义后端代理:用Node.js/Express搭建简单代理服务器,前端请求自己的后端,后端再转发请求到Deezer API,彻底避开浏览器的跨域限制。

4. 降级为串行请求

如果并发请求仍触发服务器限制,可以改成串行请求(虽速度稍慢,但能避免并发预检问题):

const fetchData = async () => {
  setIsloading(true);
  try {
    const res1 = await axios.get(url, { /* 配置 */ });
    const res2 = await axios.get(url2, { /* 配置 */ });
    setApiData([res1.data, res2.data]);
  } catch (error) {
    setIsError(error);
  } finally {
    setIsloading(false);
  }
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 06:03:16