React向Node.js发送POST请求后如何获取queueItem响应?
爬取结果返回前端的实现方案
问题本质
- simplecrawler 属于异步事件驱动的爬虫工具,原路由代码启动爬虫后,全程没有调用
response的返回方法,前端发出的POST请求会一直等待直到超时,自然拿不到响应 fetchcomplete事件会随爬取进度反复触发,如果直接在这个事件里写响应返回逻辑,会因为HTTP连接仅支持单次响应,触发“不能对已发送的响应再次写入”的报错
Node.js端路由修改
按照「逐次收集爬取到的queueItem → 等待所有爬取任务执行完成 → 统一向前端返回数据」的逻辑调整代码,修改后的可直接复用的代码:
router.post('/urls',(request, response)=>{ const targetUrl = request.body.url; const crawlDepth = request.body.depth; // 基础入参校验,避免无效请求 if (!targetUrl || !crawlDepth) { return response.status(400).json({ error: "缺少目标爬取URL或深度参数" }); } // 存储所有爬取完成的资源项 const crawlResultList = []; const Crawler = require("simplecrawler"); const crawler = Crawler(targetUrl) .on("fetchcomplete", function (queueItem) { // 仅做数据存储,不在此处直接返回响应 crawlResultList.push(queueItem); }) // 监听爬虫全量执行完成的事件 .on("complete", function () { // 所有任务跑完后,统一把收集的queueItem作为响应返回 response.json({ success: true, data: crawlResultList }); }) // 补充错误捕获,避免异常场景下请求永久挂起 .on("fetcherror", (queueItem, res) => { console.log(`资源爬取失败:${queueItem.url},返回状态码${res.statusCode}`); }) .on("crawlerror", (err) => { response.status(500).json({ success: false, error: `爬取任务执行失败:${err.message}` }); }); crawler.maxDepth = crawlDepth; crawler.maxConcurrency = 3; crawler.start(); });
React端代码适配
原前端的axios请求逻辑没有核心问题,仅需要根据爬虫的实际执行时长适当调大请求超时阈值,避免爬虫还没执行完就触发前端超时中断请求:
const SendToServer = (url) => { axios.post('http://localhost:4000/app/urls', url, { // 超时设置为120秒,适配爬虫执行周期 timeout: 120000 }) .then(response => { // 此处即可拿到后端返回的全部queueItem数据 console.log('爬取返回结果:', response.data.data); }) .catch(err => console.error('请求出错:', err)); }
扩展说明
如果业务需要实时把每一个爬取到的queueItem推给前端展示,不需要等全量爬取完成,普通的HTTP POST响应模式无法实现(单连接仅支持一次响应返回),需要改用SSE服务端推送或者WebSocket双向通信的方案。
内容的提问来源于stack exchange,提问作者Aviel Palgi
相关产品推荐
相关产品推荐

