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

Next.js 13.2.3调用本地ASP.NET Web API遇TypeError: fetch failed问题

问题:Next.js 13.2.3 调用本地ASP.NET Web API 出现 TypeError: fetch failed

本地有两个独立项目:前端使用Next.js 13.2.3,后端为ASP.NET Web API。后端API通过Swagger UI测试正常,前端能正常获取https://jsonplaceholder.typicode.com/users的数据,但调用本地后端API时抛出TypeError: fetch failed错误。已在后端配置CORS允许前端地址http://127.0.0.1:3000,且该后端在基于Vite的React项目中可正常调用。

后端CORS配置代码(Program.cs)

using Microsoft.EntityFrameworkCore;
using PropertyManagerWebAPI.Models;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

#region Set up Cors policy to be able to to talk to React client
var provider = builder.Services.BuildServiceProvider();
var configuration = provider.GetRequiredService<IConfiguration>();

builder.Services.AddCors(options =>
{
    var frontendUrl = configuration.GetValue<string>("frontend_url");

    options.AddDefaultPolicy(builder =>
    {
        builder.WithOrigins(frontendUrl).AllowAnyMethod().AllowAnyHeader();
    });
});
#endregion

//Dependency Injection of DbContext Class 
builder.Services.AddDbContext<APIDbContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("DevConnection")));

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseCors();

app.UseAuthorization();

app.MapControllers();

app.Run();

前端调用代码(src\app\dashboard\page.tsx)

async function getData() {
    const response = await fetch("https://127.0.0.1:7227/api/Properties")
    if (!response.ok) {
        throw new Error('Failed to fetch data');
    }
    return response.json()
}

export default async function ProductsPage() {
    const a: any = await getData()
    return (
        <>
            <div>
                {a.map((info: any) =>
                    <div key={info.id}>
                        {info.city}
                    </div>
                )}
            </div>
        </>
    )
}

浏览器错误信息

Uncaught TypeError: fetch failed
    at Object.fetch (C:\Users\bob\Desktop\all_important\myproject\node_modules\.pnpm\next@13.2.3_biqbaboplfbrettd7655fr4n2y\node_modules\next\dist\compiled\undici\index.js:1:26686)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
The above error occurred in the <RedirectErrorBoundary> component:

    at RedirectErrorBoundary (webpack-internal:///(app-client)/./node_modules/.pnpm/next@13.2.3_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/components/layout-router.js:361:9)
    at RedirectBoundary (webpack-internal:///(app-client)/./node_modules/.pnpm/next@13.2.3_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/components/layout-router.js:368:11)
    at NotFoundBoundary (webpack-internal:///(app-client)/./node_modules/.pnpm/next@13.2.3_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/components/layout-router.js:404:11)
    at LoadingBoundary (webpack-internal:///(app-client)/./node_modules/.pnpm/next@13.2.3_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/components/layout-router.js:317:11)
    at ErrorBoundaryHandler (webpack-internal:///(app-client)/./node_modules/.pnpm/next@13.2.3_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/components/error-boundary.js:59:9)
    at ErrorBoundary (webpack-internal:///(app-client)/./node_modules/.pnpm/next@13.2.3_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/components/error-boundary.js:72:11)
    at RenderFromTemplateContext (webpack-internal:///(app-client)/./node_modules/.pnpm/next@13.2.3_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/components/render-from-template-context.js:12:34)
    at OuterLayoutRouter (webpack-internal:///(app-client)/./node_modules/.pnpm/next@13.2.3_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/components/layout-router.js:23:11)
    at section
    at ScrollAndFocusHandler (webpack-internal:///(app-client)/./node_modules/.pnpm/next@13.2.3_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/components/layout-router.js:153:1)
    at InnerLayoutRouter (webpack-internal:///(app-client)/./node_modules/.pnpm/next@13.2.3_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/components/layout-router.js:195:11)
    at RedirectErrorBoundary (webpack-internal:///(app-client)/./node_modules/.pnpm/next@13.2.3_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/components/layout-router.js:361:9)
    at RedirectBoundary (webpack-internal:///(app-client)/./node_modules/.pnpm/next@13.2.3_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/components/layout-router.js:368:11)
    at NotFoundErrorBoundary (webpack-internal:///(app-client)/./node_modules/.pnpm/next@13.2.3_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/components/layout-router.js:397:9)
    at NotFoundBoundary (webpack-internal:///(app-client)/./node_modules/.pnpm/next@13.2.3_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/components/layout-router.js:404:11)
    at LoadingBoundary (webpack-internal:///(app-client)/./node_modules/.pnpm/next@13.2.3_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/components/layout-router.js:317:11)
    at ErrorBoundary (webpack-internal:///(app-client)/./node_modules/.pnpm/next@13.2.3_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/components/error-boundary.js:72:11)
    at RenderFromTemplateContext (webpack-internal:///(app-client)/./node_modules/.pnpm/next@13.2.3_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/components/render-from-template-context.js:12:34)
    at OuterLayoutRouter (webpack-internal:///(app-client)/./node_modules/.pnpm/next@13.2.3_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/components/layout-router.js:23:11)
    at body
    at html
    at ReactDevOverlay (webpack-internal:///(app-client)/./node_modules/.pnpm/next@13.2.3_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/components/react-dev-overlay/internal/ReactDevOverlay.js:61:9)
    at HotReload (webpack-internal:///(app-client)/./node_modules/.pnpm/next@13.2.3_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/components/react-dev-overlay/hot-reloader-client.js:20:11)
    at Router (webpack-internal:///(app-client)/./node_modules/.pnpm/next@13.2.3_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/components/app-router.js:48:11)
    at ErrorBoundaryHandler (webpack-internal:///(app-client)/./node_modules/.pnpm/next@13.2.3_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/components/error-boundary.js:59:9)
    at ErrorBoundary (webpack-internal:///(app-client)/./node_modules/.pnpm/next@13.2.3_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/components/error-boundary.js:72:11)
    at AppRouter (webpack-internal:///(app-client)/./node_modules/.pnpm/next@13.2.3_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/components/app-router.js:24:13)
    at ServerRoot (webpack-internal:///(app-client)/./node_modules/.pnpm/next@13.2.3_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/app-index.js:126:11)
    at RSCComponent
    at Root (webpack-internal:///(app-client)/./node_modules/.pnpm/next@13.2.3_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/app-index.js:143:11)

React will try to recreate this component tree from scratch using the error boundary you provided, ErrorBoundaryHandler.

怀疑同一localhost运行两个服务导致问题,替换公共API可正常运行,换npm创建新项目问题依旧。


解决方法

1. 处理服务器端证书信任问题

Next.js 13 App Router的页面默认是服务器组件,fetch请求会在Node.js服务器环境执行。本地ASP.NET Web API的自签名HTTPS证书未被Node.js信任,导致请求失败。

  • 操作步骤:
    1. 导出ASP.NET Web API的自签名证书:浏览器访问https://127.0.0.1:7227,点击地址栏锁图标 → 证书 → 详细信息 → 复制到文件,选择Base64编码格式保存。
    2. 将证书添加到系统信任列表:
      • Windows:运行certutil -addstore -f "ROOT" 证书文件路径.cer
      • macOS:运行sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain 证书文件路径.cer
      • Linux:将证书复制到/usr/local/share/ca-certificates/,执行sudo update-ca-certificates

2. 改为客户端组件执行请求

如果不想处理证书信任,可将页面改为客户端组件,让fetch在浏览器端执行(浏览器通常已信任本地自签名证书):

'use client'

import { useState, useEffect } from 'react'

async function getData() {
    const response = await fetch("https://127.0.0.1:7227/api/Properties")
    if (!response.ok) {
        throw new Error('Failed to fetch data');
    }
    return response.json()
}

export default function ProductsPage() {
    const [data, setData] = useState<any[]>([])
    const [error, setError] = useState<string | null>(null)

    useEffect(() => {
        const fetchData = async () => {
            try {
                const res = await getData()
                setData(res)
            } catch (err) {
                setError((err as Error).message)
            }
        }
        fetchData()
    }, [])

    if (error) return <div>Error: {error}</div>
    if (!data.length) return <div>Loading...</div>

    return (
        <>
            <div>
                {data.map((info) =>
                    <div key={info.id}>
                        {info.city}
                    </div>
                )}
            </div>
        </>
    )
}

3. 验证CORS配置细节

  • 确认appsettings.Development.json中的frontend_url值为http://127.0.0.1:3000(末尾不要加斜杠)。
  • 临时放宽CORS策略测试:
options.AddDefaultPolicy(builder =>
{
    builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader();
});

测试通过后再恢复严格的CORS配置。

4. 统一地址格式

前后端使用一致的地址标识:要么都用localhost,要么都用127.0.0.1,避免DNS解析或跨域标识不匹配的问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 17:02:07