Nginx限流后前端请求被拦,怎么处理429错误?

UP主~焕焕 阅读 61

我用Nginx做了限流配置,结果前端频繁调用接口时直接返回429了,页面卡住没法继续操作。有没有办法在JS里捕获这个状态并友好提示用户?

试过在axios拦截器里判断status === 429,但有时候请求压根没发出去,浏览器控制台只看到failed net::ERR_FAILED,根本拿不到响应状态码。

axios.interceptors.response.use(
  res => res,
  err => {
    if (err.response?.status === 429) {
      alert('请求太频繁,请稍后再试');
    }
    return Promise.reject(err);
  }
);
我来解答 赞 6 收藏
二维码
手机扫码查看
2 条解答
钰岩~
钰岩~ Lv1
这个问题我也遇到过,Nginx限流直接掐断请求的时候确实很恶心。给你个完整方案:

1. 首先axios拦截器要改成这样,处理请求错误和响应错误两种情况:

axios.interceptors.response.use(
response => response,
error => {
if (error.response?.status === 429 || error.code === 'ECONNABORTED') {
showRateLimitAlert()
}
return Promise.reject(error)
}
)

axios.interceptors.request.use(
config => config,
error => {
if (error.code === 'ECONNABORTED') {
showRateLimitAlert()
}
return Promise.reject(error)
}
)

function showRateLimitAlert() {
// 这里换成你自己的提示组件
alert('服务器限流了,等两秒再试')
}


2. 关键点是判断 ECONNABORTED 错误码,Nginx直接掐断请求时会触发这个。另外建议加个请求超时配置:

axios.defaults.timeout = 10000 // 10秒超时


3. 实际项目中别用alert,改成你自己的Toast组件或者状态管理。我一般会加个节流防止重复提示:

let lastAlertTime = 0
function showRateLimitAlert() {
if (Date.now() - lastAlertTime > 2000) {
toast.error('操作太频繁啦')
lastAlertTime = Date.now()
}
}


复制这个基本就能解决问题了,我项目里就这么用的。前端处理限流就这样,没办法100%完美,至少比直接卡死强。
点赞 1
2026-03-06 08:13
UP主~雯清
这问题我太熟悉了,Nginx限流直接在网关层干掉请求,前端确实拿不到429状态码,只看到 ERR_FAILED 是正常现象——因为压根没到后端,连HTTP响应都没生成。

先说结论:别指望前端能准确捕获429,得从两方面搞:

一是Nginx配置上,加个响应头,让前端能识别出来被限流了。比如在限流 zone 那块加个 add_header X-RateLimit-Retry-After $limit_req_status;,然后前端拦截器里检查这个自定义头:

axios.interceptors.response.use(
res => res,
err => {
if (err.response?.headers?.['x-ratelimit-retry-after'] === 'REJECTED') {
alert('请求太频繁,请稍后再试');
// 这里可以加个防抖重试逻辑
} else if (err.code === 'ECONNABORTED' || err.message.includes('timeout')) {
// 真·请求超时
} else if (!err.response && !err.code) {
// ERR_FAILED 大概率是Nginx挡了
alert('网络或服务端限流,请稍后再试');
}
return Promise.reject(err);
}
);


二是Nginx那块别光用 limit_req_status 429,建议改成 limit_req_status 420(虽然420不是标准码,但很多公司都这么用),或者干脆用 429 + 自定义header 双重信号,这样前端判断更可靠。

另外提醒一句,别在前端用 onerrortry catch 捞这种错误,浏览器层面根本拦不住,必须靠响应拦截器或者 axios 的 transformResponse 里做点手脚——但最稳妥的还是让Nginx返回个可识别的标识。

插件可以的话,用 nginx-ultimate-bad-bot-blocker 这类现成方案,它默认就加了 X-Request-Status 头,省得自己调。

最后说句掏心窝子的:429这事儿,前端能做的很有限,关键还是后端+网关配合给信号,别指望单靠前端兜底。
点赞 1
2026-02-27 13:10