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

如何在Node.js/Express中存储POST请求数据并在另一函数处理

问题解决思路及代码修正

核心问题梳理

  1. 请求方式不匹配:后端提供的是POST /movies接口,但前端loadMovies函数发送的是GET请求,既无法触发后端POST逻辑,也无法传递选中的复选框数据(imdbIDs数组)。
  2. 异步请求处理漏洞:后端用forEach循环发起异步http.get请求,通过index === imdbIDs.length - 1判断是否所有请求完成不可靠——异步请求的完成顺序不一定和循环顺序一致,可能导致还没收集完所有电影数据就提前返回响应。
  3. 前端响应数据获取错误:前端尝试用xhr.responseData获取响应数据是错误的,XMLHttpRequest的响应数据应该用xhr.responseText(字符串格式)或xhr.response(解析后的对象,需设置响应类型)。

前端代码修正(index.js)

修改loadMovies函数,改为发送POST请求,传入选中的imdbIDs数组,并正确处理响应:

function loadMovies(selectedImdbIDs) { // 接收选中的imdbIDs数组作为参数
  const xhr = new XMLHttpRequest();
  xhr.onload = function () {
    const mainElement = document.querySelector("main");

    // 清空main内容
    while (mainElement.childElementCount > 0) {
      mainElement.firstChild.remove();
    }

    if (xhr.status === 200) {
      try {
        const movies = JSON.parse(xhr.responseText); // 正确解析响应文本
        movies.forEach(movie => new MovieBuilder(movie, deleteMovie).appendTo(mainElement));
      } catch (parseError) {
        mainElement.append(`解析数据失败: ${parseError.message}`);
      }
    } else {
      mainElement.append(`数据加载失败,状态码 ${xhr.status} - ${xhr.statusText}`);
    }
  };

  // 设置请求头,告诉后端发送的是JSON数据
  xhr.open("POST", "/movies");
  xhr.setRequestHeader("Content-Type", "application/json");
  // 发送选中的imdbIDs数组(转为JSON字符串)
  xhr.send(JSON.stringify(selectedImdbIDs));
}

// 调用示例:从复选框中获取选中的imdbIDs
// const selectedImdbIDs = Array.from(document.querySelectorAll('input[type="checkbox"]:checked'))
//                              .map(checkbox => checkbox.value);
// loadMovies(selectedImdbIDs);

后端代码修正(server.js)

用Promise封装每个http.get请求,通过Promise.all等待所有请求完成后再返回响应,避免异步顺序问题:

// 建议用https(OMDB支持https),保持请求协议一致性
const https = require('https');

// 必须先配置JSON解析中间件,放在POST接口之前
app.use(express.json());

app.post("/movies", async function (req, res) {
  const imdbIDs = req.body; 

  if (!Array.isArray(imdbIDs)) {
    return res.sendStatus(400); 
  }

  const apiKEY = '########';
  // 封装http.get为Promise,方便异步控制
  const fetchMovie = (imdbID) => {
    return new Promise((resolve, reject) => {
      const apiUrl = `https://www.omdbapi.com/?apikey=${apiKEY}&i=${imdbID}`;

      https.get(apiUrl, (response) => {
        let responseData = '';

        response.on('data', (chunk) => {
          responseData += chunk;
        });

        response.on('end', () => {
          try {
            const movieData = JSON.parse(responseData);
            if (movieData.Response === 'True') {
              const movie = {
                Released: new Date(movieData.Released).toISOString(),
                Runtime: movieData.Runtime !== 'N/A' ? parseInt(movieData.Runtime) : null,
                Genres: movieData.Genre.split(',').map(genre => genre.trim()),
                Directors: movieData.Director.split(',').map(director => director.trim()),
                Writers: movieData.Writer.split(',').map(writer => writer.trim()),
                Actors: movieData.Actors.split(',').map(actor => actor.trim()),
                MetaScore: movieData.Metascore !== 'N/A' ? parseInt(movieData.Metascore) : null,
                imdbRating: Number(movieData.imdbRating)
              };
              resolve(movie);
            } else {
              console.error(`获取电影失败 imdbID: ${imdbID},错误: ${movieData.Error}`);
              resolve(null); // 失败时返回null,后续过滤掉无效项
            }
          } catch (error) {
            console.error('解析电影数据失败:', error);
            resolve(null);
          }
        });
      }).on('error', (error) => {
        console.error('请求OMDB接口失败:', error);
        resolve(null);
      });
    });
  };

  // 并发请求所有电影数据,等待全部完成
  const moviePromises = imdbIDs.map(id => fetchMovie(id));
  const results = await Promise.all(moviePromises);
  // 过滤掉请求失败的null项
  const movies = results.filter(movie => movie !== null);

  res.status(200).send(movies);
});

额外注意事项

  1. 后端必须配置express.json()中间件,才能正确解析前端发送的JSON格式请求体。
  2. OMDB API支持HTTPS协议,建议后端使用https.get发起请求,避免浏览器安全警告和潜在的请求失败问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 15:40:04