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

Next.js 13.4 App Router部署后fetch请求报net::ERR_BLOCKED_BY_CLIENT错误

Next.js 13.4 App Router部署后fetch抛出net::ERR_BLOCKED_BY_CLIENT错误解决方案

问题场景

使用Next.js v13.4 App Router开发前端项目,搭配独立后端,通过app目录下的api文件夹管理路由。本地环境中注册/登录功能正常,但部署到远程Ubuntu服务器后,前端的fetch()函数抛出net::ERR_BLOCKED_BY_CLIENT错误。经测试:

  • 后端服务无问题,curl和Postman直接请求后端接口均正常返回
  • 使用关闭所有插件的隐私窗口访问前端,错误依然存在

代码片段

'use client';
import {NextPage} from 'next';
import {Formik, Form} from 'formik';
import * as Yup from 'yup';
import CrButton from '@/components/CrButton';
import logger from '@/utils/logger';
import useTheme from '@/utils/hooks/useTheme';
import {useEffect, useState} from 'react';
import {useRouter} from 'next/navigation';
import {toast} from 'react-toastify';

interface Props {
  section: string;
}

interface Values {
  email: string;
  password: string;
}

async function register(values: Values, role: string) {
  const res = await fetch(
    `http://localhost:3000/api/add?email=${values.email}&password=${
      values.password
    }&role=${role.toUpperCase()}`,
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
    }
  );

  const json = await res.json();

  return json;
}

const SubRegisterPage: NextPage<Props> = ({section, ...rest}) => {
  //...省略其他代码
  async function handleOnSubmit(values: Values) {
    const res = await register(values, role);
    if (res.data.code === 200) {
      router.push('/login');
      toast.success('Aramıza katıldın, giriş yapmayı unutma!');
    }
    if (res.data.code == 1004) {
      toast.error(res.data.message);
    }
  }
}

核心原因

代码中register函数的fetch请求URL写死为http://localhost:3000/api/add:

  • 本地开发时,前端和后端都运行在本地机器,localhost指向自身,请求能正常到达后端
  • 部署到远程服务器后,前端页面通过公网域名/IP访问,此时浏览器执行fetch时,会将localhost:3000解析为用户的本地机器,而非部署后端的远程服务器。这种无效请求会被浏览器拦截,从而抛出net::ERR_BLOCKED_BY_CLIENT错误。

修复方案

方案1:使用相对路径(推荐,适用于前后端同域名部署)

将fetch的URL改为相对路径/api/add,Next.js会自动根据当前页面的域名/IP拼接完整请求地址,本地和部署环境无需额外配置:

async function register(values: Values, role: string) {
  const res = await fetch(
    `/api/add?email=${values.email}&password=${values.password}&role=${role.toUpperCase()}`,
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
    }
  );

  const json = await res.json();
  return json;
}

方案2:使用环境变量(适用于前后端分离、不同域名部署)

  1. 在项目根目录创建.env.production文件,添加后端服务的公网地址:
NEXT_PUBLIC_API_BASE_URL=https://你的后端域名或服务器IP:端口
  1. 修改代码中的fetch URL,通过环境变量拼接:
async function register(values: Values, role: string) {
  const res = await fetch(
    `${process.env.NEXT_PUBLIC_API_BASE_URL}/api/add?email=${values.email}&password=${values.password}&role=${role.toUpperCase()}`,
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
    }
  );

  const json = await res.json();
  return json;
}

额外验证步骤

  1. 确保远程服务器上的Next.js项目已执行npm run build完成构建,并用npm start或PM2等进程管理器启动
  2. 若使用Nginx反向代理,检查配置是否正确转发前端的/api请求到后端服务
  3. 确认远程服务器防火墙已开放后端服务的端口,公网可正常访问

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 04:23:14