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

JavaScript中Fetch请求遇JSON输入意外结束及405错误排查

Node.js + Express POST请求报错:405 Method Not Allowed 及 Unexpected end of JSON input

我用Node.js和Express搭建服务器,前端通过Fetch向/api路由发送POST请求时,同时出现「Unexpected end of JSON input」和「405 Method Not Allowed」错误,试过各类博客及平台方案均无效,贴出代码请求排查:

客户端脚本

checkButton.addEventListener("click", () => {
  const text = textArea.value;

  fetch("/api", {
    body: JSON.stringify({text}),
    headers: {
      "Content-Type": "application/json",
    },
    method: "POST",
  })
    .then((res) => res.json())
    .then((data) => {
      console.log(data);
      similarityPercentageSpan.textContent = `${data.similarity}%`;
      const processedText = data.processedText;
      // Do something with the processed text.
      console.log(processedText);
      const similarPartsList = document.getElementById("similarPartsList");
      similarPartsList.innerHTML = "";

      if (data.similarParts) {
        data.similarParts.forEach((part) => {
          const li = document.createElement("li");
          const link = document.createElement("a");
          link.href = part.url;
          link.textContent = part.text;
          li.appendChild(link);
          similarPartsList.appendChild(li);
        });
      }
    })
    .catch((error) => {
      console.error("Error:", error);
    });
});

服务器端/api路由代码

app.post("/api", async (req, res) => {
  try {
    const userText = req.body.text;
    const numberOfPhrases = 5;
    const phraseLength = 100;
    const extractedPhrases = getRandomPhrases(
      userText,
      numberOfPhrases,
      phraseLength
    );
    const scrapedAndProcesseContent = [];
    const similarityScore = calculateTextSimilarity(userText, cleanedContent);
    for (const phrase of extractedPhrases) {
      const searchResults = await fetchGoogleSearchResults(phrase);
      const cleanedContent = cleanScrapedContent(searchResults);
      const similarParts = [];
      for (const result of searchResults) {
        similarParts.push({
          text: result.text,
          url: result.url,
        });
      }

      scrapedAndProcesseContent.push({
        phrase,
        similarityScore,
        cleanedContent,
        similarParts: [],
      });
    }
    res.json({
      similarity: similarityScore,
      processedText: scrapedAndProcesseContent,
    });
  } catch (error) {
    console.error("Error:", error);
    res.status(500).json({error: "An error occurred"});
  }
});

排查与修复方案

1. 解决「405 Method Not Allowed」错误

这个错误表明服务器未正确处理/api路径的POST请求,核心修复点:

  • 添加JSON解析中间件:Express默认不会解析JSON请求体,必须在所有路由前挂载express.json(),否则req.body会是undefined,甚至导致路由匹配异常。在服务器入口文件添加:
    const express = require('express');
    const app = express();
    
    // 必须放在路由定义之前
    app.use(express.json());
    
    // 之后再定义你的/api路由
    app.post("/api", async (req, res) => { /* ... */ });
    
  • 检查路由冲突:确认没有其他代码对/api定义了其他HTTP方法(如GET),或路由顺序导致POST路由未被匹配。
  • 跨域场景配置CORS:若前端与服务器运行在不同端口,安装cors包并配置:
    npm install cors
    
    服务器代码添加:
    const cors = require('cors');
    app.use(cors());
    

2. 解决「Unexpected end of JSON input」错误

该错误是因为前端尝试解析非JSON响应(如空响应、HTML错误页)导致的,需结合405问题修复,同时处理以下问题:

  • 修复变量提前引用错误:服务器代码中similarityScore定义时用到了cleanedContent,但这个变量是在后续for循环中才声明的,会抛出ReferenceError,导致服务器返回异常响应。调整代码逻辑,确保cleanedContent在使用前被定义:
    // 移除提前定义的similarityScore
    const scrapedAndProcesseContent = [];
    
    for (const phrase of extractedPhrases) {
      const searchResults = await fetchGoogleSearchResults(phrase);
      const cleanedContent = cleanScrapedContent(searchResults);
      // 在此处计算当前phrase的相似度,或根据业务逻辑调整
      const similarityScore = calculateTextSimilarity(userText, cleanedContent);
      // ... 剩余代码
    }
    
  • 前端增加响应状态校验:在解析JSON前先检查响应状态,避免解析错误响应:
    fetch("/api", { /* ... */ })
      .then((res) => {
        if (!res.ok) throw new Error(`请求失败,状态码:${res.status}`);
        return res.json();
      })
      .then(data => { /* ... */ })
      .catch(error => { /* ... */ });
    

3. 额外优化点

  • 修正拼写错误:服务器代码中scrapedAndProcesseContent应为scrapedAndProcessedContent(少了一个's'),避免后续逻辑潜在问题。
  • 确保异步错误被捕获:确认fetchGoogleSearchResults等异步函数内部的错误能被外层try/catch捕获,避免未处理的Promise rejection。

内容的提问来源于stack exchange,提问作者Jideofor Enukoha-Efobi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 18:56:06