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

Next.js 13客户端调用API路由报错:返回HTML而非有效JSON

问题排查:Next.js 13客户端组件调用API路由解析JSON失败

问题场景

使用Next.js 13作为后端框架、React作为前端框架,从客户端组件调用API路由获取JSON数据时,控制台能看到服务器返回JSON,但客户端抛出错误:Uncaught (in promise) SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON"

核心原因及解决方案

1. API路由写法不符合Next.js 13 App Router规范

Next.js 13的App Router中,API路由必须通过export async function GET(而非默认导出函数)的方式定义,且参数获取逻辑和旧版Pages Router不同:

  • 路径参数(如id)需从第二个参数的params属性中获取
  • 查询参数(如size、style)需通过request.nextUrl.searchParams获取

修正后的API路由代码:

import db from "../../../../utils/db";
import Product from "../../../../models/Product";
import { NextResponse } from "next/server";

// 采用App Router要求的导出方式
export async function GET(request, { params }) {
  try {
    await db.connectDb();
    const { id } = params; // 正确获取路径参数
    const searchParams = request.nextUrl.searchParams;
    const size = searchParams.get('size');
    const style = searchParams.get('style');

    const product = await Product.findById(id).lean();
    if (!product) {
      return NextResponse.json({ message: "产品不存在" }, { status: 404 });
    }

    const subProduct = product.subProducts[style];
    if (!subProduct) {
      return NextResponse.json({ message: "款式不存在" }, { status: 404 });
    }

    const sizeData = subProduct.sizes[size];
    if (!sizeData) {
      return NextResponse.json({ message: "尺寸不存在" }, { status: 404 });
    }

    let discount = subProduct.discount;
    let priceBefore = sizeData.price;
    let price = discount ? priceBefore - priceBefore / discount : priceBefore;

    await db.disconnectDb();

    return NextResponse.json({
      _id: product._id,
      style: Number(style),
      name: product.name,
      description: product.description,
      slug: product.slug,
      sku: subProduct.sku,
      brand: product.brand,
      category: product.category,
      subCategories: product.subCategories,
      shipping: product.shipping,
      images: subProduct.images,
      color: subProduct.color,
      size: sizeData.size,
      price,
      priceBefore,
      quantity: sizeData.qty,
    });
    
  } catch (error) {
    console.error(error);
    return NextResponse.json(
      { message: error.message },
      { status: 500 }
    );
  }
}

2. API路由文件结构错误

Next.js 13 App Router的API路由必须放在app/api/[路由路径]/route.js路径下。例如,如果你的API路径是/api/product/[id],则文件必须命名为app/api/product/[id]/route.js,否则Next.js会返回HTML格式的404页面,导致JSON解析失败。

3. 客户端请求路径优化

客户端请求时建议使用相对路径,避免硬编码http://localhost:3000,方便后续部署:

async function handleClick() {
    const response = await fetch(`/api/product/${product._id}?style=${product.style}&size=${dsize}`, {
      method: "GET",
      headers: {
        "Content-Type": "application/json",
        Accept: "application/json",
      },
    });
  const data = await response.json();
  console.log(data);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 07:25:33