javascript - NextJS API | 应用程序在部署和开发模式下工作,但在我运行下一次构建时却不行 | 被拒绝
问题描述
描述错误
我已经使用 NextJS 构建了一个具有内部 API 的应用程序,并且我使用 getStaticProps 方法来查询 API。
您可以在此处找到已部署的应用程序:https ://tailor-challenge.vercel.app/
还有这里的 github 存储库:在此处输入链接描述
该应用程序在开发模式下完美运行,我在 Vercel 中进行的部署也可以正常运行。但是当我运行下一个构建命令时,出现以下错误:
Build error occurred
FetchError: request to http://localhost:3000/api/restaurants failed, reason: connect ECONNREFUSED 127.0.0.1:3000
at ClientRequest.<anonymous> (/home/silinde87/Jobs/tailor/TailorChallenge/node_modules/node-fetch/lib/index.js:1461:11)
at ClientRequest.emit (node:events:376:20)
at Socket.socketErrorListener (node:_http_client:474:9)
at Socket.emit (node:events:376:20)
at emitErrorNT (node:internal/streams/destroy:188:8)
at emitErrorCloseNT (node:internal/streams/destroy:153:3)
at processTicksAndRejections (node:internal/process/task_queues:80:21) {
type: 'system',
errno: 'ECONNREFUSED',
code: 'ECONNREFUSED'
}
info - Collecting page data .npm ERR! code 1
npm ERR! path /home/silinde87/Jobs/tailor/TailorChallenge
npm ERR! command failed
npm ERR! command sh -c next build
NextJS 内部 API
/api/restaurants/index.js
export default function handler(req, res) {
const { method } = req;
switch (method) {
case 'GET':
getRestaurants();
break;
default:
res.status(405).end(`Method ${req.method} Not Allowed`);
}
function getRestaurants() {
const restaurants = data;
res.status(200).json(restaurants);
}
}
/api/restaurants/[id].js
export default function handler(req, res) {
const { id } = req.query;
const { method } = req;
switch (method) {
case 'GET':
getRestaurantById();
break;
default:
res.status(405).end(`Method ${req.method} Not Allowed`);
}
function getRestaurantById() {
const restaurants = data.find((el) => el.id.toString() === id.toString());
if (restaurants) res.status(200).json(restaurants);
else res.status(405).end(`There is no Restaurant with id: ${id}`);
}
}
NextJS 的页面
pages/index.js <-- 我在哪里获取餐馆列表
export async function getStaticProps() {
const res = await fetch(`${process.env.NEXT_PUBLIC_NEXTAUTH_URL}/api/restaurants`);
const restaurants = await res.json();
if (!restaurants) {
return {
notFound: true,
};
}
return {
props: {
restaurants,
},
};
}
页面/[id].js
// Return a list of possible value for id
export async function getStaticPaths() {
const res = await fetch(`${process.env.NEXT_PUBLIC_NEXTAUTH_URL}/api/restaurants`);
const restaurants = await res.json();
let paths = restaurants.map(({ id }) => {
return {
params: {
id: id.toString(),
},
};
});
return { paths, fallback: false };
}
// Fetch necessary data for the restaurant details using params.id
export async function getStaticProps({ params }) {
const res = await fetch(`${process.env.NEXT_PUBLIC_NEXTAUTH_URL}/api/restaurants/${params.id}`);
const restaurantData = await res.json();
return {
props: {
restaurantData,
},
};
}
解决方案
我从官方文档中引用了这段话,链接如下:
注意:您不应该使用 fetch() 来调用 >getStaticProps 中的 API 路由。相反,直接导入您的 API 路由内部使用的逻辑。您可能需要针对 > 这种方法稍微重构您的代码。
从外部 API 获取很好!
https://nextjs.org/docs/basic-features/data-fetching
基本上是因为 getStaticProps 或 getStaticPaths 里面的代码永远不会在浏览器中执行,所以你可以安全地直接在那里调用数据源。
此外,由于构建时应用程序未运行,因此发生故障,因此 localhost api 不可用。您可以通过在另一个终端窗口中通过“yarn dev”或“npm run dev”运行应用程序并在另一个终端窗口中构建应用程序来确认这一点。这样它应该构建得很好,但不推荐这样做。我会重构代码,以便在这些 getStaticProps 和 getStaticPaths 函数中不获取此应用程序的 api。
getServerSideProps 也是如此,它也只是在服务器上运行,所以你也不应该在那里获取 api。只有浏览器应该对 api 进行获取,例如,如果您希望用户能够将一些数据发布到应用程序。
推荐阅读
- reactjs - 将 Google 或 Facebook Oauth 访问令牌存储在 AsyncStorage 中以在 React Native 中进行登录身份验证是否安全?
- c# - C# 中的 CefSharp 构建问题
- yaml - 在 azure 管道 yaml 文件中,PowerShell 命令可以在 bash 中运行吗?
- node.js - $slice 在 mongoDB 的嵌入式文档中不起作用
- android - 当应用程序在后台时,Android 会提供缓存的本地化
- asp.net-core - 获取角色列表作为列表
结果是 ASP.NET Core Web API - python - 检测地图中的棕色区域并计算其面积
- c# - 如何将运行状况检查添加到 .Net 核心后台服务
- php - 从表单输入中检索数据
- pandas - Pandas 减去不适用于 .iloc 的列