NextJS getServerSideProps调用Laravel API失败求助
问题:Next.js调用Laravel API出现ECONNREFUSED错误
环境与背景
正在开发Next.js用户设置页面,Laravel后端提供/api/user接口(通过Token验证保护),接口正常返回用户数据:
{ "data": { "id": "2", "name": "Testing User", "email": "testing@mctestface.com", "updated_at": "2022-08-23T10:39:32.000000Z", "created_at": "2022-08-23T10:39:32.000000Z" } }
预期逻辑:通过Cookie中的Token调用接口,响应200则设置页面props,401则重定向到登录页,但实际访问页面时显示404,进入catch分支。已单独验证接口和Token功能正常,但代码调用失败。
当前代码实现
Next.js页面组件(Settings)
import React from 'react' import httpRequest from '@/lib/httpRequest' import { getCookie } from '@/lib/session' const Settings = ({ dashboardUser }) => { return ( <div> <p>Protected Page</p> </div> ) } export async function getServerSideProps({ req }) { try { const resDashboardUser = await httpRequest.get({ url: '/api/user', token: getCookie('token', req) }) if (resDashboardUser.status === 200) { return { props: { dashboardUser: resDashboardUser.data } } } } catch (error) { if (error?.response?.status === 401) { return { redirect: { destination: '/login', permanent: false } } } return { notFound: true } } } export default Settings
httpRequest的get方法实现
get: ({ baseUrl = process.env.NEXT_PUBLIC_BACKEND_URL, url, token, params }) => { return axios({ timeout: process.env.NEXT_PUBLIC_API_TIMEOUT, method: 'get', baseURL: baseUrl, url: url, headers: { Accept: 'application/json', 'Content-Type': 'application/json', Authorization: 'Bearer ' + token || '' }, params: params }); },
错误信息
Promise { <pending> } error - unhandledRejection: AxiosError: connect ECONNREFUSED 127.0.0.1:80 at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1138:16) { port: 80, address: '127.0.0.1', syscall: 'connect', code: 'ECONNREFUSED', errno: -111, config: { transitional: { silentJSONParsing: true, forcedJSONParsing: true, clarifyTimeoutError: false }, adapter: [Function: httpAdapter], transformRequest: [ [Function: transformRequest] ], transformResponse: [ [Function: transformResponse] ], timeout: '30000', xsrfCookieName: 'XSRF-TOKEN', xsrfHeaderName: 'X-XSRF-TOKEN', maxContentLength: -1, maxBodyLength: -1, env: { FormData: [Function] }, validateStatus: [Function: validateStatus], headers: { Accept: 'application/json', 'Content-Type': 'application/json', Authorization: 'Bearer 8|jcL6IL08oMqKET2r0Skhjx1Dw02UTeToNukQpqm4', 'User-Agent': 'axios/0.27.2' }, method: 'get', baseURL: 'http://localhost', url: '/api/user', data: undefined }, request: <ref *1> Writable { _writableState: WritableState { objectMode: false, highWaterMark: 16384, finalCalled: false, needDrain: false, ending: false, ended: false, finished: false, destroyed: false, decodeStrings: true, defaultEncoding: 'utf8', length: 0, writing: false, corked: 0, sync: true, bufferProcessing: false, onwrite: [Function: bound onwrite], writecb: null, writelen: 0, afterWriteTickInfo: null, buffered: [], bufferedIndex: 0, allBuffers: true, allNoop: true, pendingcb: 0, constructed: true, prefinished: false, errorEmitted: false, emitClose: true, autoDestroy: true, errored: null, closed: false, closeEmitted: false, [Symbol(kOnFinished)]: [] }, _events: [Object: null prototype] { response: [Function: handleResponse], error: [Function: handleRequestError], socket: [Array] }, _eventsCount: 3, _maxListeners: undefined, _options: { maxRedirects: 21, maxBodyLength: 10485760, protocol: 'http:', path: '/api/user', method: 'GET', headers: [Object], agent: undefined, agents: [Object], auth: undefined, hostname: 'localhost', port: null, nativeProtocols: [Object], pathname: '/api/user' }, _ended: true, _ending: true, _redirectCount: 0, _redirects: [], _requestBodyLength: 0, _requestBodyBuffers: [], _onNativeResponse: [Function (anonymous)], _currentRequest: ClientRequest { _events: [Object: null prototype], _eventsCount: 7, _maxListeners: undefined, outputData: [], outputSize: 0, writable: true, destroyed: false, _last: true, chunkedEncoding: false, shouldKeepAlive: false, _defaultKeepAlive: true, useChunkedEncodingByDefault: false, sendDate: false, _removedConnection: false, _removedContLen: false, _removedTE: false, _contentLength: 0, _hasBody: true, _trailer: '', finished: true, _headerSent: true, _closed: false, socket: [Socket], _header: 'GET /api/user HTTP/1.1\r\n' + 'Accept: application/json\r\n' + 'Content-Type: application/json\r\n' + 'Authorization: Bearer 8|jcL6IL08oMqKET2r0Skhjx1Dw02UTeToNukQpqm4\r\n' + 'User-Agent: axios/0.27.2\r\n' + 'Host: localhost\r\n' + 'Connection: close\r\n' + '\r\n', _keepAliveTimeout: 0, _onPendingData: {}, agent: [Agent], socketPath: undefined, method: 'GET', maxHeaderSize: undefined, insecureHTTPParser: undefined, path: '/api/user', _ended: false, res: null, aborted: false, timeoutCb: null, upgradeOrConnect: false, parser: null, maxHeadersCount: null, reusedSocket: false, host: 'localhost', protocol: 'http:', _redirectable: [Circular *1], [Symbol(kCapture)]: false, [Symbol(kNeedDrain)]: false, [Symbol(corked)]: 0, [Symbol(kOutHeaders)]: [Object: null prototype] }, _currentUrl: 'http://localhost/api/user', _timeout: null, [Symbol(kCapture)]: false } }
问题分析与解决方案
核心问题
错误日志显示请求地址为http://localhost/api/user,默认使用80端口,但Laravel默认通过php artisan serve启动在8000端口,导致后端服务不在80端口监听,触发连接拒绝错误。
修复步骤
修正后端地址环境变量
在项目根目录的.env文件中,更新NEXT_PUBLIC_BACKEND_URL为Laravel实际运行地址,包含正确端口:NEXT_PUBLIC_BACKEND_URL=http://localhost:8000重启Next.js开发服务器确保环境变量生效。
验证环境变量值
可以在getServerSideProps中临时打印变量确认:console.log('Backend URL:', process.env.NEXT_PUBLIC_BACKEND_URL)修复Token拼接逻辑
当前Authorization: 'Bearer ' + token || ''存在逻辑缺陷,若token为falsy值(如undefined),会生成'Bearer undefined',应修改为:Authorization: token ? `Bearer ${token}` : ''优化错误处理
避免将所有错误都返回404,区分认证错误和连接错误:catch (error) { if (error?.response?.status === 401) { return { redirect: { destination: '/login', permanent: false } } } // 连接错误等其他情况,可重定向到错误页或返回提示 console.error('API请求失败:', error) return { redirect: { destination: '/server-error', permanent: false } } }
内容的提问来源于stack exchange,提问作者BigJobbies
相关产品推荐
相关产品推荐

