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

Next.js项目调用无JSON返回的DELETE API报错排查求助

问题排查与解决方案

核心问题

你的代码存在两个关键问题,导致DELETE接口调用报错:

  1. 成功响应强制解析JSON:DELETE接口常返回204 No Content(无响应体),此时调用response.json()会因没有可解析的JSON数据抛出语法错误。
  2. 错误响应强制解析JSON:当接口返回非JSON格式的错误信息时,await response.json()同样会报错,且该错误会被外层catch捕获,导致无法正确处理错误逻辑。

修改后的代码

import { handleError } from "./errors";

type fetcherProps = {
  url: string;
  method: "GET" | "POST" | "PUT" | "DELETE";
  data?: any;
  options?: FetcherOptions;
  toast?: boolean;
  hasToken?: null | string | boolean;
};

interface FetcherOptions extends Omit<RequestInit, "body"> {
  headers?: Record<string, string>;
}

const responseHandler = (err: any) => {
  if (err) {
    if (err.details?.[0]?.message) {
      return err.details[0].message;
    } else if (err.message) {
      return err.message;
    }
  }
};

export const REACT_BASE_ROUTE = "https://example.com/fa/";
export const BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL;
export const BASE_URL_SSR = process.env.NEXT_PUBLIC_API_BASE_URL_SSR;

export const ConfigApi = async ({
  url,
  method = "GET",
  data = null,
  options = {},
  toast = false,
  hasToken = null,
}: fetcherProps) => {
  try {
    const config: RequestInit = {
      method,
      headers: {
        "Content-Type": "application/json",
        authorization: hasToken ? `Bearer ${hasToken}` : "",
        ...options.headers,
      },
      ...options,
    };

    if (data && (method === "POST" || method === "PUT")) {
      config.body = JSON.stringify(data);
    }

    const response = await fetch(
      (options.next ? BASE_URL_SSR : BASE_URL) + url,
      config
    );

    if (!response.ok) {
      let errorResponse;
      try {
        // 尝试解析JSON错误响应
        errorResponse = await response.json();
      } catch {
        // 解析失败则获取文本内容兜底
        errorResponse = await response.text();
      }
      
      if (toast) {
        handleError(response.status, responseHandler(errorResponse) || errorResponse);
      }
      return null;
    }

    // 处理成功响应:204状态码直接返回,其他情况解析JSON
    if (response.status === 204) {
      return null; // 或返回空对象{},根据业务需求调整
    }
    
    try {
      return await response.json();
    } catch {
      // 若成功响应但非JSON格式,返回文本内容
      return await response.text();
    }
  } catch (error) {
    console.error("API请求异常:", error);
    return null;
  }
};

关键修改点说明

  • 错误响应处理:用try/catch包裹response.json(),解析失败时降级为response.text(),避免因非JSON响应导致报错。
  • 成功响应处理:判断状态码为204时直接返回(符合HTTP规范,DELETE成功常返回204);其他成功状态尝试解析JSON,失败则返回文本内容。
  • 代码细节优化:authorization拼接改为模板字符串更简洁,增加异常日志便于排查。

后端接口验证建议

如果前端修改后仍有问题,可验证后端接口:

  • 检查DELETE接口的响应状态码,是否符合HTTP规范(成功建议返回204)。
  • 确认错误响应的格式,尽量统一为JSON格式,便于前端处理;若无法修改,前端已做降级处理可兼容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 11:12:22