Next.js API请求出现双URL拼接错误问题排查
问题
使用Next.js 13时,通过axios发起注册API请求,控制台出现错误拼接的URL:http://localhost:3000/'http:/localhost:8000/api/register。已在.env.local中配置环境变量NEXT_PUBLIC_API=http://localhost:8000/api,怀疑问题与组件位于app目录有关,相关代码如下:
'use client'; import React, { useState } from 'react'; import { useRouter } from 'next/navigation'; import axios from 'axios'; import toast from 'react-hot-toast'; const Register = () => { const [name, setName] = useState(''); const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const [loading, setLoading] = useState(false); const router = useRouter(); const handleSubmit = async e => { e.preventDefault(); console.log(name, email, password); // Make API request try { setLoading(true); const { data } = await axios.post( `${process.env.NEXT_PUBLIC_API}/register`, { name, email, password } ); setLoading(false); log('register => ', data); toast.success('Register Success!'); router.push('/'); } catch (error) { setLoading(false); toast.error(error.response.data.error); console.log(error); } }; return ( <div className='container'> <div className='d-flex justify-content-center align-items-center vh-100 '> <div className='row border border-light border-1 border-secondary rounded shadow pb-5 pt-5'> <h2 className='mb-5 text-center'>Register</h2> <form action='' onSubmit={handleSubmit}> <input type='text' value={name} onChange={e => setName(e.target.value)} placeholder='Enter your name' className='form-control mb-3' /> <input type='email' value={email} onChange={e => setEmail(e.target.value)} placeholder='Enter your email' className='form-control mb-3' /> <input type='password' value={password} onChange={e => setPassword(e.target.value)} placeholder='Enter your email' className='form-control mb-3' /> <div className='d-grid'> <button className='btn btn-primary text-align-center' disabled={loading || !name || !email || !password} > {loading ? ( <div className='spinner-border spinner-border-sm text-light'> <span className='visually-hidden'></span> </div> ) : ( 'Submit' )} </button> </div> </form> </div> </div> </div> ); }; export default Register;
排查与解决
检查环境变量格式:打开
.env.local,确认NEXT_PUBLIC_API没有被单引号或双引号包裹。正确格式应为:NEXT_PUBLIC_API=http://localhost:8000/api若变量值带引号,拼接时会把引号带入URL,导致出现
'http:/localhost:8000/api'这类错误内容,同时axios会把带引号的错误路径当作相对路径,拼接到当前页面域名后,形成最终错误URL。验证环境变量加载:在组件的
handleSubmit函数开头添加console.log(process.env.NEXT_PUBLIC_API),查看输出是否为预期的http://localhost:8000/api。若输出带引号或为空,说明环境变量配置错误或未加载。重启开发服务器:修改
.env.local后必须重启Next.js开发服务器,否则新的环境变量不会生效。优化axios配置(可选):全局配置axios的baseURL,避免每次手动拼接路径出错。在组件顶部添加:
axios.defaults.baseURL = process.env.NEXT_PUBLIC_API;之后请求可简化为:
const { data } = await axios.post('/register', { name, email, password });关于app目录的影响:app目录下的客户端组件(标记
'use client')可以正常访问NEXT_PUBLIC_前缀的环境变量,因此问题与组件所在目录无关,核心原因是环境变量配置或加载异常。
内容的提问来源于stack exchange,提问作者timbo245

