Nginx限流后前端请求被拦,怎么处理429错误?
我用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);
}
);
ERR_FAILED是正常现象——因为压根没到后端,连HTTP响应都没生成。先说结论:别指望前端能准确捕获429,得从两方面搞:
一是Nginx配置上,加个响应头,让前端能识别出来被限流了。比如在限流 zone 那块加个
add_header X-RateLimit-Retry-After $limit_req_status;,然后前端拦截器里检查这个自定义头:二是Nginx那块别光用
limit_req_status 429,建议改成limit_req_status 420(虽然420不是标准码,但很多公司都这么用),或者干脆用429 + 自定义header双重信号,这样前端判断更可靠。另外提醒一句,别在前端用
onerror或try catch捞这种错误,浏览器层面根本拦不住,必须靠响应拦截器或者 axios 的transformResponse里做点手脚——但最稳妥的还是让Nginx返回个可识别的标识。插件可以的话,用
nginx-ultimate-bad-bot-blocker这类现成方案,它默认就加了X-Request-Status头,省得自己调。最后说句掏心窝子的:429这事儿,前端能做的很有限,关键还是后端+网关配合给信号,别指望单靠前端兜底。