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

Node Express中node-fetch服务端正常客户端报错问题求助

问题排查与解决方案

核心问题总结

你的代码存在四个关键问题,导致了客户端报错、参数丢失以及NASA API返回无效错误:

  1. 服务端变量名冲突,覆盖了Express的响应对象
  2. 服务端重复发送HTTP响应,引发异常
  3. 客户端POST请求未携带rover参数,导致服务端获取不到有效值
  4. HTML表单缺少火星车名称输入字段,无法提交有效参数

逐个问题修复与代码修正

1. 服务端代码修正

const express = require('express');
const path = require('path');
const fetch = require('node-fetch');
const bodyParser = require('body-parser');
const cors = require('cors');

const app = express();

app.use('/', express.static(path.join(__dirname, '../public')));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json()); // 新增:支持解析JSON格式请求体
app.use(cors("*"));

app.post('/userinput', async (request, response) => {
  const rover = request.body.rover;
  console.log("SERVER SIDE ROVER: ", rover);

  // 新增参数校验
  if (!rover) {
    return response.status(400).json({ error: "必须输入火星车名称" });
  }

  try {
    // 重命名变量避免覆盖Express的response对象
    const nasaResponse = await fetch(`https://api.nasa.gov/mars-photos/api/v1/rovers/${rover}/latest_photos?api_key=DH46IQlx0gMyXPmLAgkxXDSPo2OrbIjPs8OJLj6L`);
    const gallery = await nasaResponse.json();
    // 仅发送一次响应,避免重复报错
    return response.json({ gallery });
  } catch (err) {
    console.log(`RESPONSE STATUS: ${response.status}`, err);
    return response.status(500).json({ error: "获取火星车图片失败" });
  }
});

const port = 3000;
app.listen(port, () => {
  console.log(`Server running on port ${port}`);
});

修复点说明:

  • 新增bodyParser.json(),支持解析客户端发送的JSON请求体
  • 将fetch的响应变量重命名为nasaResponse,避免覆盖Express的response对象
  • 移除混用的.then语法,统一使用await,代码逻辑更清晰
  • 增加参数校验,当rover为空时返回400错误
  • 移除多余的return response.json(),避免重复发送响应引发异常

2. 客户端代码修正

const getRoverPhotos = async (state, fn) => {
  // 获取用户输入的火星车名称
  const roverInput = document.querySelector('input[name="rover"]');
  const roverName = roverInput?.value?.trim();

  if (!roverName) {
    alert("请输入火星车名称(例如curiosity)");
    return [];
  }

  try {
    const response = await fetch("http://localhost:3000/userinput", {
      method: "POST",
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ rover: roverName }) // 新增:传递rover参数
    });

    console.log("RESPONSE CLIENT: ", response);

    // 新增HTTP状态校验
    if (!response.ok) {
      throw new Error(`请求失败,状态码:${response.status}`);
    }

    const jsonImageData = await response.json();
    console.log("JSON Image Data", jsonImageData);

    // 新增数据存在性判断,避免ReferenceError
    if (!jsonImageData.gallery?.latest_photos) {
      console.log("未找到图片或火星车名称无效");
      return [];
    }

    const ImageData = jsonImageData.gallery.latest_photos.map(photo => photo.img_src);
    const newState = jsonImageData.gallery;
    updateStore(store, newState);
    return ImageData;
  } catch (err) {
    console.error("获取图片失败:", err);
    return [];
  }
};

// 绑定表单提交事件,而非页面加载时直接调用
document.querySelector('form').addEventListener('submit', async (e) => {
  e.preventDefault(); // 阻止表单默认跳转行为
  await getRoverPhotos(store, updateStore);
});

修复点说明:

  • 新增获取用户输入的逻辑,从表单输入框读取火星车名称
  • 在fetch请求中添加body,发送JSON格式的rover参数
  • 增加HTTP响应状态校验,处理请求失败的情况
  • 增加数据存在性判断,避免Uncaught ReferenceError
  • 将getRoverPhotos绑定到表单提交事件,避免页面加载时无参数调用

3. HTML表单修正

<form action="http://localhost:3000/userinput" method="POST">
  <input type="text" name="rover" placeholder="输入火星车名称(如curiosity)" required>
  <button id="submit" name="submit">Send Images</button>
</form>

修复点说明:

  • 添加rover输入字段,让用户可以输入火星车名称
  • 增加required属性,确保用户输入后才能提交表单

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 23:19:01