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:使用环境变量(适用于前后端分离、不同域名部署)
- 在项目根目录创建
.env.production文件,添加后端服务的公网地址:
NEXT_PUBLIC_API_BASE_URL=https://你的后端域名或服务器IP:端口
- 修改代码中的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; }
额外验证步骤
- 确保远程服务器上的Next.js项目已执行
npm run build完成构建,并用npm start或PM2等进程管理器启动 - 若使用Nginx反向代理,检查配置是否正确转发前端的/api请求到后端服务
- 确认远程服务器防火墙已开放后端服务的端口,公网可正常访问
内容的提问来源于stack exchange,提问作者MrPand
相关产品推荐
相关产品推荐

