NextJS的getStaticProps/getServerSideProps在Vercel部署异常求助
部署Next.js页面到Vercel时getStaticProps/getServerSideProps报错问题
问题背景
本地使用getStaticProps或getServerSideProps的Next.js页面运行正常,但部署到Vercel时出现以下问题:
- 使用getStaticProps时触发构建错误
- 使用getServerSideProps时页面显示Internal Server Error
相关页面代码
import React from 'react'; import {Wrapper} from "#layouts"; import axios from "axios"; function PrivacyPolicy({data}) { return ( <Wrapper> {data && <div className="conditions" dangerouslySetInnerHTML={{__html: data}} /> } </Wrapper> ); } export async function getStaticProps() { const settings = await axios.get(`${process.env.BASE_URL}/getSettings`).then(res => res.data); return { props: { data: settings?.confident_agree } } } export default PrivacyPolicy;
getStaticProps构建错误日志
[GET] /_next/data/xIyCYnTjWYvq1SkNn0EfE/privacy-policy.json 14:05:24:19 nt-length': '699', date: 'Wed, 20 Jul 2022 11:05:26 GMT', 'alt-svc': 'quic=":443"; ma=2592000; v="43,46", h3-Q043=":443"; ma=2592000, h3-Q046=":443"; ma=2592000, h3-Q050=":443"; ma=2592000, h3-25=":443"; ma=2592000, h3-27=":443"; ma=2592000' }, config: { transitional: [Object], adapter: [Function: httpAdapter], transformRequest: [Array], transformResponse: [Array], timeout: 0, xsrfCookieName: 'XSRF-TOKEN', xsrfHeaderName: 'X-XSRF-TOKEN', maxContentLength: -1, maxBodyLength: -1, env: [Object], validateStatus: [Function: validateStatus], headers: [Object], method: 'get', url: 'xxx/api/getSettings', data: undefined }, request: <ref *1> 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, socket: [TLSSocket], _header: 'GET /api/getSettings HTTP/1.1\r\n' + 'Accept: application/json, text/plain, */*\r\n' + 'Access-Control-Allow-Origin: *\r\n' + 'Access-Control-Allow-Credentials: true\r\n' + 'Access-Control-Allow-Methods: GET,PUT,POST,DELETE\r\n' + 'Content-Type: application/json\r\n' + 'User-Agent: axios/0.27.2\r\n' + 'Connection: close\r\n' + '\r\n', _keepAliveTimeout: 0, _onPendingData: [Function: noopPendingOutput], agent: [Agent], socketPath: undefined, method: 'GET', maxHeaderSize: undefined, insecureHTTPParser: undefined, path: '/api/getSettings', _ended: true, res: [IncomingMessage], aborted: false, timeoutCb: null, upgradeOrConnect: false, parser: null, maxHeadersCount: null, reusedSocket: false, host: 'popil.berataras.com', protocol: 'https:', _redirectable: [Writable], [Symbol(kCapture)]: false, [Symbol(kNeedDrain)]: false, [Symbol(corked)]: 0, [Symbol(kOutHeaders)]: [Object: null prototype] }, data: '<!DOCTYPE html>\n' + '<html style="height:100%">\n' + '<head>\n' + '<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />\n' + '<title> 403 Forbidden\r\n' + '</title></head>\n' + '<body style="color: #444; margin:0;font: normal 14px/20px Arial, Helvetica, sans-serif; height:100%; background-color: #fff;">\n' + '<div style="height:auto; min-height:100%; "> <div style="text-align: center; width:800px; margin-left: -400px; position:absolute; top: 30%; left:50%;">\n' + ' <h1 style="margin:0; font-size:150px; line-height:150px; font-weight:bold;">403</h1>\n' + '<h2 style="margin-top:20px;font-size: 30px;">Forbidden\r\n' + '</h2>\n' + '<p>Access to this resource on the server is denied!</p>\n' + '</div></div></body></html>\n' }, page: '/privacy-policy' } RequestId: fd64c257-6f5c-46fa-b1d3-e2e8ef855bd7 Error: Runtime exited with error: exit status 1 Runtime.ExitError
getServerSideProps错误情况
页面显示Internal Server Error:
问题分析与解决方案
从日志可见,axios请求后端API时返回403 Forbidden,这是核心问题。以下是针对性解决步骤:
1. 检查Vercel环境变量配置
- 确认
BASE_URL已在Vercel项目的「Settings > Environment Variables」中正确配置,确保是完整的API地址(例如https://your-api-domain.com,注意路径拼接是否正确) - 部署前可在Vercel控制台的「Deployments」中查看构建日志,确认环境变量是否正常加载
2. 放行Vercel IP到后端白名单
Vercel构建/运行环境的IP会被部分后端服务器拦截,可:
- 查询Vercel官方公布的IP段,将其添加到后端服务器的防火墙/安全组白名单
- 测试阶段可暂时关闭后端的IP限制,验证是否解决问题
3. 添加错误捕获逻辑
避免因API请求失败导致构建崩溃,修改getStaticProps/getServerSideProps:
export async function getStaticProps() { try { const settings = await axios.get(`${process.env.BASE_URL}/getSettings`).then(res => res.data); return { props: { data: settings?.confident_agree } }; } catch (error) { console.error('获取设置失败:', error); // 返回默认数据或空值,保证构建完成 return { props: { data: null } }; } }
4. 改用Next.js内部API路由
将API请求逻辑转移到Next.js的pages/api目录,避免外部IP拦截:
- 创建
pages/api/getSettings.js:
export default async function handler(req, res) { try { // 直接调用后端内部服务,或安全转发请求 const response = await fetch('https://your-backend-domain/getSettings'); const settings = await response.json(); res.status(200).json(settings); } catch (error) { res.status(500).json({ error: '获取设置失败' }); } }
- 修改页面中的请求地址:
const settings = await axios.get('/api/getSettings').then(res => res.data);
5. 清理不必要的请求头
日志中显示axios携带了后端才需要设置的CORS头(如Access-Control-Allow-Origin),这些会被服务器识别为异常请求,清理后重新请求:
const settings = await axios.get(`${process.env.BASE_URL}/getSettings`, { headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' // 移除所有CORS相关请求头 } }).then(res => res.data);
内容的提问来源于stack exchange,提问作者Berat
相关产品推荐
相关产品推荐

