Axios GET传递多ID参数返回204且请求耗时过长问题咨询
问题诊断与解决方案
核心问题定位
- GET请求传body不符合HTTP规范:HTTP协议中GET请求的body没有定义语义,绝大多数代理、CDN、服务端都会直接忽略GET请求携带的body内容。你当前代码通过
axios.get的data字段传递序列号列表,服务端根本接收不到该参数。 - 服务端执行了慢查询:因为拿不到序列号列表,服务端只能对你传入的整个时间范围做全表扫描,遍历所有数据后没有匹配到符合条件的结果,才会耗时近20分钟最终返回204 No Content。
- 你之前切换POST请求后问题仍存在,大概率是POST的参数格式不符合服务端要求,服务端还是没有正确解析到序列号参数,仍然执行了全表扫描逻辑。
修复步骤
- 优先改用POST请求传递参数,避免GET请求的参数长度限制,按服务端要求的格式传递参数,示例代码如下:
var formattedstartTime = moment(startTime) .utc() .format() .toString(); var formattedendTime = moment(endTime) .utc() .format() .toString(); // 序列号先去重,避免重复参数增加查询负担 const modemSerials = [...new Set(networks.map((p) => p.modemSerial))]; useEffect(() => { dispatch(setPerformanceLvls(null)); axios .post( config.API_PERFORMACE, // 按服务端要求的字段名传递参数,不要手动拼接逗号,直接传数组axios会自动序列化 { startTime: formattedstartTime, endTime: formattedendTime, modemSerials: modemSerials } ) .then((res) => { const pd: PerfomanceData[] = res.data; const pdMap = pd.reduce((acc, curr) => { acc[curr.deviceSerialNumber] = curr; return acc; }, {}); setData(pdMap); const plvlMap = pd.reduce((acc, curr) => { acc[curr.deviceSerialNumber] = curr.perfomanceLevel; return acc; }, {}); dispatch(setPerformanceLvls(plvlMap)); setDataFetched(true); }) .catch((error) => { console.log("can not load data", error); }); }, [dispatch, formattedendTime, formattedstartTime, modemSerials]);
- 如果服务端仅支持GET请求,将序列号放在
params字段中传递,axios会自动将参数拼接到URL的query部分:
axios.get(config.API_PERFORMACE, { params: { startTime: formattedstartTime, endTime: formattedendTime, modemSerials: modemSerials.join(',') } })
- 若单次查询的序列号数量超过100个,建议拆分为多批并行请求,每批查询20-30个序列号,最后合并结果,避免单次查询压力过大导致慢查询。
- 联系后端确认查询逻辑是否添加了
deviceSerialNumber和时间字段的联合索引,没有索引的情况下大数量级查询必然会出现超时问题。
内容的提问来源于stack exchange,提问作者You Me
相关产品推荐
相关产品推荐

