Next.js中用TRPC处理大数据失败,遇431请求头过大错误
问题解决:TRPC批量提交Excel数据时出现431请求头过大错误
错误原因
你当前的代码对Excel的每一行数据单独发起一次TRPC请求,500行就会产生500个并发请求。这种做法不仅效率极低,还会触发浏览器或服务器的请求限制,导致net::ERR_CONNECTION_RESET 431 (Request Header Fields Too Large)错误。
解决方案
核心思路是将单条请求改为批量请求,把所有行数据整理成数组后一次性提交,大幅减少请求数量。
1. 修改前端代码,收集所有数据后批量提交
<Input id="fileInput" className="hidden" type="file" onChange={async (e) => { console.log('找到文件: ' + e.target.files![0]); const file = e.target.files![0]; if(!file){ toast.error('未找到文件'); return; } const data = await file.arrayBuffer(); const workbook = XLSX.read(data); const sheetNameList = workbook.SheetNames; // 收集所有待提交的批量数据 const bulkData = []; sheetNameList.forEach(sheetName => { const rowData = XLSX.utils.sheet_to_json(workbook.Sheets[sheetName]!); console.log('所有行数据'); console.log(rowData); rowData.forEach((row: any) => { bulkData.push({ basePrice: row['BasePrice'], gstRate: row['GstRate'], totalPrice: row['TotalPrice'], commissionValue: row['CommissionValue'], productCategory: ProductCategory.CLASSICTSHIRT, classicTshirtSize: row['ClassicTshirtSize'], classicTshirtColor: row['ClassicTshirtColor'], classicTshirtFront: row['ClassicTshirtFront'] === 'Y', }); }); }); // 一次性提交所有数据 mutation.mutate(bulkData); toast.success('数据处理中,请稍候'); }} />
2. 更新TRPC Mutation配置
const mutation = trpc.product.bulkUpdateMasterPrice.useMutation({ onSuccess: (data) => { console.log('数据处理完成'); toast.success('批量更新成功'); }, onError: (error) => { console.error(error); toast.error('批量更新失败,请重试'); }, });
3. 修改后端TRPC接口,支持批量数据接收
// 后端TRPC路由示例 export const productRouter = router({ bulkUpdateMasterPrice: mutation({ // 定义输入为数组类型 input: z.array(z.object({ basePrice: z.number(), gstRate: z.number(), totalPrice: z.number(), commissionValue: z.number(), productCategory: z.enum([ProductCategory.CLASSICTSHIRT]), classicTshirtSize: z.string(), classicTshirtColor: z.string(), classicTshirtFront: z.boolean(), })), async resolve({ input }) { // 批量写入MongoDB await ProductModel.insertMany(input); // 如果是更新操作,可使用updateMany或其他批量逻辑 return { success: true }; }, }), });
备选方案(无需修改后端时)
如果暂时无法调整后端接口,可以采用分批提交的方式,比如每次提交50条数据,避免一次性发起过多请求:
// 在收集完bulkData后 const batchSize = 50; for (let i = 0; i < bulkData.length; i += batchSize) { const batch = bulkData.slice(i, i + batchSize); await mutation.mutateAsync(batch); }
但这种方式仍不如批量接口高效,优先推荐修改后端支持批量提交。
内容的提问来源于stack exchange,提问作者Rishabh
相关产品推荐
相关产品推荐

