NextJS SSR环境下Axios报Z_BUFF_ERROR问题求助
NextJS SSR服务端axios请求失败问题解决
问题描述
我开发了一个NextJS应用,采用SSR预渲染方式从API获取数据(服务端和客户端使用相同的数据获取函数)。客户端运行正常,但部署在Vercel的服务端出现了错误。
示例代码
报错写法一
const http = axios.create({ baseURL: apiURL() }) export const fetchProjects = (tags: string[] | number[] = [], page: number = 1 ) => async () => (await(http.get(`${appConfig.PROJECTS_ENDPOINT}?${queryString({tags, page})}`))).data
报错写法二
export const fetchProjects = (tags: string[] | number[] = [], page: number = 1 ) => async (): Promise<any> => ( axios.get(`${apiURL()}${appConfig.PROJECTS_ENDPOINT}?${queryString({tags, page})}`, { headers: { 'Accept': 'application/json', 'Accept-Language': 'en,ru;q=0.9', } }).then(response => { return response.data; }).catch(error => { console.error(error); throw error; }) )
正常运行写法
替换为以下基于原生fetch的写法后,服务端和客户端均运行正常:
export const fetchProjects = (tags: string[] | number[] = [], page: number = 1 ) => async () => ( new Promise((resolve, reject) => { fetch( `${apiURL()}${appConfig.PROJECTS_ENDPOINT}?${queryString({tags, page})}`, { headers: { 'Accept': 'application/json', 'Accept-Language': 'en,ru;q=0.9' } } ).then(response => { response.json().then(data => resolve(data)); }) .catch(error => { console.error(error); reject(error); }) }) )
问题原因分析
出现这个问题的核心原因,大概率是axios在Vercel服务端环境下存在兼容性或配置问题:
apiURL()函数在服务端执行时,可能返回了错误的地址(比如未区分客户端/服务端环境变量),导致axios请求失败- axios的部分依赖或默认适配器在Vercel的服务端运行环境中无法正常工作,而原生fetch是NextJS服务端环境默认支持的API,兼容性更好
解决方案
方案1:修复axios配置继续使用
如果想保留axios,可做以下调整:
- 避免在创建axios实例时直接调用
apiURL(),改为在请求时动态传入地址,避免服务端初始化时的地址错误 - 显式指定服务端兼容的适配器,避免默认适配器的兼容性问题
- 用
params参数自动处理查询字符串,避免手动拼接的错误
调整后的代码示例:
import axios from 'axios'; import httpAdapter from 'axios/lib/adapters/http'; const http = axios.create(); // 仅在服务端环境使用http适配器 if (typeof window === 'undefined') { http.defaults.adapter = httpAdapter; } export const fetchProjects = (tags: string[] | number[] = [], page: number = 1 ) => async () => { const response = await http.get(`${apiURL()}${appConfig.PROJECTS_ENDPOINT}`, { params: { tags, page }, headers: { 'Accept': 'application/json', 'Accept-Language': 'en,ru;q=0.9' } }); return response.data; };
同时务必检查apiURL()函数,确保它在服务端环境下能正确读取环境变量(比如Vercel配置的环境变量),生成合法的API地址。
方案2:改用原生fetch API(推荐)
原生fetch在NextJS的服务端和客户端环境下都有良好的支持,无需额外依赖,兼容性更强。可以进一步简化你的fetch写法,让代码更简洁:
export const fetchProjects = (tags: string[] | number[] = [], page: number = 1 ) => async () => { const url = `${apiURL()}${appConfig.PROJECTS_ENDPOINT}?${queryString({tags, page})}`; try { const response = await fetch(url, { headers: { 'Accept': 'application/json', 'Accept-Language': 'en,ru;q=0.9' } }); // 主动检查请求是否成功 if (!response.ok) throw new Error(`请求失败:${response.status}`); return await response.json(); } catch (error) { console.error(error); throw error; } };
内容的提问来源于stack exchange,提问作者Almaron
相关产品推荐
相关产品推荐

