next.js 如何从`getStaticProps`请求API路由[duplicate]

wmvff8tz  于 2023-06-05  发布在  其他
关注(0)|答案(2)|浏览(371)

此问题已在此处有答案

Fetch error when building Next.js static website in production(1个答案)
去年关闭。
我想在网站上显示来自YouTube频道的最新视频。通道每天最多上传一次,所以我在我的vercel.json中缓存了1天(86400秒)的API路由响应,如下所示:

{
    "headers": [
        {
            "source": "/(.*)",
            "headers": [
                {
                    "key": "access-control-allow-origin",
                    "value": "*"
                },
                {
                    "key": "Cache-Control",
                    "value": "s-maxage=86400"
                }
            ]
        }
    ]
}

我想使用带有增量静态重新生成的getStaticProps,这样我的API路由每天最多只收到一次发送的请求,但我不确定如何将请求写入我的API路由。
Next.js文档说:

**注意:**不要使用fetch()调用getStaticProps中的API路由。相反,直接导入API路由中使用的逻辑。对于这种方法,您可能需要稍微重构代码。

从外部API获取是可以的!
这是什么意思?我现在写请求的方法是不是错了?

// /pages/index.js

import Header from '../components/header/header'
import MainContent from '../components/main-content/main-content'
import Footer from '../components/footer/footer'

export default function Index({ videoTitle, videoURL, videoThumbnailData }) {
    return (
        <>
            <Header />

            <MainContent
                videoTitle={videoTitle}
                videoURL={videoURL}
                videoThumbnailData={videoThumbnailData}
            />

            <Footer />
        </>
    )
}

// Called at build time, and response revalidated after 1 day (86400 seconds)
// since internal API response is cached on Vercel Edge network for 1 day (see /pages/api/get-latest-video.js)
export async function getStaticProps() {
    // Fetch YouTube videos from internal API route /pages/api/get-latest-video.js
    const res = await fetch(`${process.env.API_ROUTES_URL}/api/get-latest-video`)
    const data = await res.json()

    // Returned as props to page
    return {
        props: {
            videoTitle: data.videoTitle,
            videoURL: data.videoURL,
            videoThumbnailData: data.videoThumbnailData
        },
        revalidate: 86400
    }
}
// /components/main-content/main-content.js

import Section from './section'
import Image from 'next/image'

export default function MainContent({ videoTitle, videoURL, videoThumbnailData }) {
    return (
        <main>
            <Section>
                <a href={videoURL}>
                    {videoTitle}
                </a>
                <Image
                    src={videoThumbnailData.url}
                    width={videoThumbnailData.width}
                    height={videoThumbnailData.height}
                />
            </Section>
        </main>
    )
}
7bsow1i6

7bsow1i61#

您的请求/api/get-latest-video应该从浏览器发送到服务器,那么服务器可能有某种路由处理程序,如:

routeMatches('/api/get-latest-video', ( req, res )=>{
    requestDB('latestVideos').then( latestVideos => {
        respondWithLatestVideos( req, res, latestVideos );
    })
});

现在,getStaticProps在服务器端运行。因此,您可以直接在getStaticProps中请求数据库,而不是向请求数据库的服务器发送请求。

export async function getStaticProps() {
    // Fetch YouTube videos from internal API route /pages/api/get-latest-video.js
    // const res = await fetch(`${process.env.API_ROUTES_URL}/api/get-latest-video`)
    // const data = await res.json()
    const data = await requestDB('latestVideos')
    ...
}

在同一个NextJs文档页面的下面还有一个稍微更详细的说明“直接编写服务器端代码”:
请注意,getStaticProps仅在服务器端运行。它永远不会在客户端运行。它甚至不会包含在浏览器的JS包中。这意味着您可以编写诸如直接数据库查询之类的代码,而无需将它们发送到浏览器。您不应该从getStaticProps获取API路由,而是可以直接在getStaticProps中编写服务器端代码。

xyhw6mcr

xyhw6mcr2#

这意味着您只需将API函数导入到getStaticProps中,而不是使用Fetch

// /pages/index.js

import Header from "../components/header/header";
import MainContent from "../components/main-content/main-content";
import Footer from "../components/footer/footer";

export default function Index({ videoTitle, videoURL, videoThumbnailData }) {
  return (
    <>
      <Header />

      <MainContent
        videoTitle={videoTitle}
        videoURL={videoURL}
        videoThumbnailData={videoThumbnailData}
      />

      <Footer />
    </>
  );
}

// Called at build time, and response revalidated after 1 day (86400 seconds)
// since internal API response is cached on Vercel Edge network for 1 day (see /pages/api/get-latest-video.js)
export async function getStaticProps() {
  // Fetch YouTube videos from internal API route /pages/api/get-latest-video.js
  const res = await getApiData(); // import your api function here
  const data = await res.json();

  // Returned as props to page
  return {
    props: {
      videoTitle: data.videoTitle,
      videoURL: data.videoURL,
      videoThumbnailData: data.videoThumbnailData,
    },
    revalidate: 86400,
  };
}

相关问题