You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用for循环在Express.js创建多app.get请求时仅返回最后URL内容的问题

问题分析与解决方案

嘿,这个坑我刚入行的时候也踩过!你现在遇到的是两个典型问题:var 作用域导致的循环变量绑定错误,还有错误的路由注册逻辑,咱们一步步捋清楚:

1. 核心问题:为什么总是返回最后一个URL的内容?

你用 var i 声明循环变量,var 是函数级作用域,循环里所有的 app.get 回调共享同一个 i 变量。等你的Express服务启动完成,循环早就跑完了,i 的值已经变成了数组的最后一个索引(因为你循环条件是 i < articleUrlArray.length-1)。所以不管什么时候访问 /news/news-desc,都会请求 articleUrlArray[i],也就是最后一个URL的内容。

2. 额外问题:重复注册同一个路由完全没必要

你在循环里多次调用 app.get('/news/news-desc', ...),这相当于给同一个路径绑定了N个回调函数,但你真正想要的应该是访问这个路径时一次性获取所有URL的文章内容,而不是注册一堆重复的路由。

修复后的完整代码

咱们直接重构逻辑,既解决作用域问题,又修正路由逻辑:

let articleUrlArray = [ 
'https://techcrunch.com/2018/05/19/shared-housing-startups-are-taking-off/', 
'https://techcrunch.com/2018/05/19/my-data-request-lists-guides-to-get-data-about-you/', 
'https://techcrunch.com/2018/05/19/siempos-new-app-will-break-your-smartphone-addiction/', 
'https://techcrunch.com/2018/05/19/la-belle-vie-wants-to-compete-with-amazon-prime-now-in-paris/', 
'https://techcrunch.com/2018/05/19/apple-started-paying-15-billion-european-tax-fine/', 
'https://techcrunch.com/2018/05/19/original-content-dear-white-people/', 
'https://techcrunch.com/2018/05/19/meet-the-judges-for-the-tc-startup-battlefield-europe-at-vivatech/', 
'https://techcrunch.com/2018/05/18/nasas-newest-planet-hunting-satellite-takes-a-stellar-first-test-image/', 
'https://techcrunch.com/video-article/turning-your-toys-into-robots-with-circuit-cubes/', 
'https://techcrunch.com/2018/05/18/does-googles-duplex-violate-two-party-consent-laws/' 
]; 

// 只注册一次路由,在路由内部批量处理所有URL请求
app.get('/news/news-desc', function(req, res) { 
  const techCrunchNewsItems = [];
  // 把每个request请求包装成Promise,方便批量处理
  const requestPromises = articleUrlArray.map(url => {
    return new Promise((resolve, reject) => {
      request(url, function(err, response, html) {
        if (err) return reject(err);
        const $ = cheerio.load(html);
        const firstParagraph = $('.article-content').children('p').eq(0).text();
        const newsItem = { bodyOne: firstParagraph };
        
        // 判断第一段长度是否不足50词,不足则添加第二段
        if (firstParagraph.split(' ').length <= 50) {
          newsItem.bodyTwo = $('.article-content').children('p').eq(1).text();
        }
        resolve(newsItem);
      });
    });
  });

  // 等待所有请求完成后,统一返回结果
  Promise.all(requestPromises)
    .then(allArticles => res.json(allArticles))
    .catch(error => res.status(500).json({ error: error.message }));
});

关键修改说明

  • 去掉了循环注册路由的逻辑,改为在单个路由内部批量处理所有URL,符合你想要获取所有内容的需求。
  • 用 map 遍历数组,每个URL对应一个独立的Promise,避免了var的作用域问题,确保每个请求都绑定正确的URL。
  • 用 Promise.all 处理所有异步请求,保证所有文章内容都获取完成后再返回给前端,不会出现返回部分内容的情况。
  • 替换了 res.send(JSON.stringify(data)) 为Express自带的 res.json(),自动处理JSON序列化,代码更简洁。

参考运行结果

运行结果截图

内容的提问来源于stack exchange,提问作者Eunicorn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:22:22