Next.js getStaticProps调用Laravel API报错:connect ECONNREFUSED ::1:8000
问题分析与解决办法
问题出在哪
getStaticProps 是Next.js做静态站点生成(SSG)时,在构建阶段的服务器端/本地环境执行的代码,和浏览器里运行的逻辑完全不一样:
- 浏览器里用相对URL,会自动补全当前页面的域名,但服务器端(构建时)没有浏览器的上下文,相对URL会默认指向
localhost或者当前服务器的本地地址。这时候如果构建时Laravel服务没启动,或者构建环境(比如CI的容器)访问不到你的本地::1:8000,就会直接报连接拒绝的错。 - 你说模拟API能用,大概率是因为那个API是第三方公共的,配置了完整的绝对URL,或者模拟服务在构建环境里能访问到。
怎么解决
给服务器端请求配置完整的Laravel API地址
在/lib/axios.ts里,区分浏览器和服务器端的baseURL:import axios from 'axios'; // 浏览器端用相对URL,自动适配当前域名;服务器端用环境变量里的完整地址 const baseURL = typeof window !== 'undefined' ? '/api' : process.env.NEXT_PUBLIC_LARAVEL_API_URL; const api = axios.create({ baseURL }); export default api;然后在项目根目录的
.env.local里添加:NEXT_PUBLIC_LARAVEL_API_URL=http://localhost:8000/api生产构建时,把这个变量换成线上Laravel API的完整地址即可。
构建时确保Laravel服务处于运行状态
本地执行next build的话,先启动Laravel服务(php artisan serve);如果是CI/CD环境,要么确保构建流程里先启动Laravel,要么直接用线上已部署好的API地址来构建。换用
getServerSideProps(如果不需要纯静态页面)
要是你不需要纯静态生成的页面,只是想初始加载时填充数据,可以换成getServerSideProps——它每次请求都会在服务器端执行,只要Next.js和Laravel在同一个服务器或者可互相访问的网络里,不管是相对URL还是正确配置的绝对URL都能正常用。不过这样就失去了SSG的性能优势,按需选择即可。SWR与预填充数据要配合到位
用getStaticProps拿到数据后,要把数据作为初始值传给SWR,避免页面加载后重复请求:export async function getStaticProps() { const initialData = await fetcher('/dashboard/data'); return { props: { initialData } }; } export default function Dashboard({ initialData }) { const { data } = useSWR('/dashboard/data', fetcher, { initialData }); // 页面渲染逻辑 }
内容的提问来源于stack exchange,提问作者Joshua Galit
相关产品推荐
相关产品推荐

