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

控制台偶发429状态码请求失败错误求助

解决OpenWeatherMap API返回429状态码的问题

首先咱们先把问题点透:429状态码就是「请求次数过多」,是OpenWeatherMap的API服务端在提醒你,你的调用频率或者总次数已经超过了它给你分配的配额限制,所以才会偶发出现请求挂起、超时,有时候又能正常加载的情况——毕竟限流是按时间窗口统计的,偶尔触达上限就会报错,没超的时候就正常。

结合你提供的代码片段(用了Promise和axios.all批量请求),给你几个针对性的解决办法:


1. 先确认你的API密钥配额

先去OpenWeatherMap的账号后台查一下你当前API密钥的限制:免费版一般是每分钟最多60次请求,每天最多1000次,如果你的业务调用量已经摸到这个上限,要么优化请求逻辑,要么考虑升级付费版。

2. 给批量请求加频率控制

你用了axios.all,会一次性把所有请求发出去,很容易在短时间内触发每分钟的请求限制。改成顺序请求+固定间隔的方式,避免瞬间打满配额:

// 定义一个延迟函数
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));

// 批量请求改为顺序执行,每次间隔1秒(适配免费版60次/分钟的限制)
const sequentialRequests = async (requests) => {
  const results = [];
  for (const req of requests) {
    results.push(await req);
    await delay(1000);
  }
  return results;
};

// 替换原来的axios.all调用
let getWeather = new Promise(function(resolve, reject) {
  getCity.then(apiData => {
    // 把你的axios请求数组放这里
    const weatherRequests = [
      axios.get('...'),
      axios.get('...')
    ];
    sequentialRequests(weatherRequests)
      .then(resolve)
      .catch(reject);
  });
});

3. 给429错误加智能重试逻辑

偶发的429可以通过重试解决,但不能无脑重试——用指数退避策略(每次重试的间隔翻倍),避免再次触发限流:

// 带指数退避重试的请求函数
const fetchWithRetry = async (axiosConfig, retries = 3, delayMs = 1000) => {
  try {
    return await axios(axiosConfig);
  } catch (error) {
    // 只有429错误且还有重试次数时才重试
    if (error.response?.status === 429 && retries > 0) {
      await new Promise(resolve => setTimeout(resolve, delayMs));
      // 下次重试间隔翻倍
      return fetchWithRetry(axiosConfig, retries - 1, delayMs * 2);
    }
    // 其他错误或者重试耗尽,直接抛出
    throw error;
  }
};

// 在你的请求中使用这个函数
let getWeather = new Promise(function(resolve, reject) {
  getCity.then(apiData => {
    axios.all([
      fetchWithRetry({ url: '...', method: 'get' }),
      fetchWithRetry({ url: '...', method: 'get' })
    ])
    .then(resolve)
    .catch(reject);
  });
});

4. 缓存请求结果,减少重复调用

天气数据更新频率不高,把已经获取的结果缓存起来(比如用localStorage或者内存缓存),相同城市的请求直接用缓存,不用每次都调用API:

// 从缓存获取天气数据(有效期10分钟)
const getCachedWeather = (cityId) => {
  const cached = localStorage.getItem(`weather_${cityId}`);
  if (cached) {
    const { data, timestamp } = JSON.parse(cached);
    if (Date.now() - timestamp < 10 * 60 * 1000) {
      return Promise.resolve(data);
    }
  }
  return null;
};

// 保存天气数据到缓存
const saveWeatherToCache = (cityId, data) => {
  localStorage.setItem(`weather_${cityId}`, JSON.stringify({
    data,
    timestamp: Date.now()
  }));
};

// 修改你的getWeather逻辑,加入缓存判断
let getWeather = new Promise(function(resolve, reject) {
  getCity.then(apiData => {
    const cityId = apiData.id; // 假设apiData里有城市唯一标识
    getCachedWeather(cityId)
      .then(cachedData => {
        if (cachedData) {
          resolve(cachedData);
          return;
        }
        // 没有缓存才发起API请求
        axios.all([/* 你的请求数组 */])
          .then(results => {
            saveWeatherToCache(cityId, results);
            resolve(results);
          })
          .catch(reject);
      })
      .catch(reject);
  });
});

最后还要排查一下你的页面逻辑:有没有重复调用getWeather的情况?比如组件重复挂载、用户频繁触发请求按钮,这些都会额外消耗你的请求配额。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:55:03