NextJs 网站不会在 Vercel 部署的网站上获取新帖子。它适用于本地主机

问题描述 投票:0回答:1

**页面.jsx **

"use client"
import React, { useState, useEffect } from 'react';
import PostCard from '@/components/PostCard/page';
import { BASE_API_URL } from '@/utils/constants';

const Home = () => {
  const [blogs, setBlogs] = useState([]);
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState(null);

  useEffect(() => {
    const fetchPosts = async () => 
    {
      setIsLoading(true);
      try {
        const res = await fetch(`${process.env.NEXT_PUBLIC_BASE_API_URL}/api/posts`,{
          cache:"no-store",
        });
        if (!res.ok) {
          throw new Error('Failed to fetch posts');
        }
        const data = await res.json();
        setBlogs(data);
      } catch (error) {
        setError(error);
      } finally {
        setIsLoading(false);
      }
    };

    fetchPosts();
  }, []);

  return (
    <div className='container mx-auto border-rose-500 flex flex-col gap-4 flex-wrap justify-center w-5/6 md:w-3/6'>
      <div className='flex flex-col'>
        <div>
          <h1 className='text-3xl md:text-5xl font-bold mb-8 text-white'>My Blogs</h1>
        </div>
        {isLoading && <div className="loader">Loading...</div>}
        {error && <div className="error">{error.message}</div>}
        {blogs.length > 0 && (
          <div className="flex flex-col gap-2 mb-8 w-full">
            {blogs.map((post) => (
              <PostCard data={post} key={post._id} />
            ))}
          </div>
        )}
        {!isLoading && !error && blogs.length === 0 && (
          <div className="empty-state">No posts found.</div>
        )}
      </div>
    </div>
  );
};

export default Home;

postDesc/[slug].jsx:

import { BASE_API_URL } from "@/utils/constants";
import React from "react";
import Markdown from 'react-markdown';
import Image from 'next/image';


async function getPostById(slug) {
  const res = await fetch(`${process.env.NEXT_PUBLIC_BASE_API_URL}/api/posts/${slug}`, {
    cache: "no-store",
  });
  if (!res.ok) {
    throw new Error("Fetching Post Failed!");
  }
  return res.json();
}


const PostDetail = async ({ params }) => {

  const post = await getPostById(params.slug);

  const formatDateString = (dateString) => {
    const dateObject = new Date(dateString);
    const options = { day: "2-digit", month: "long", year: "2-digit" };
    return dateObject.toLocaleDateString("en-GB", options).replace(/\//g, " ");
  };

  const handleImageTag = (domNode) => {
    if (domNode.type === 'tag' && domNode.name === 'img') {
      // Customize styling for the img tag
      return <Image {...domNode.attribs} alt="img" className="w-full h-80 object-center my-4" width={0}
      height={0}
      sizes="100vw"
      style={{ width: '100%', height: "320px" }} />;
    }
    return null;
  };

  const options = {
    replace: handleImageTag,
  };


  return (
    <div class="max-w-screen-lg mx-auto mb-8 md:w-3/6">
      <main>
        <div class="mb-4 md:mb-0 w-full mx-auto relative">
          <Image
            alt="img"
            src={post.img}
            width={0}
            height={0}
            sizes="100vw"
            style={{ width: '100%', height: "320px" }}
            className="transition-opacity ease-in duration-700 opacity-80 w-full h-96 object-cover lg:rounded p-4 md:p-0"
          />
        </div>
        <div className="flex flex-col items-center mt-8">
          <h2 class="text-3xl text-center md:text-normal md:text-5xl font-semibold text-white leading-tight mb-4 px-2">
            {post.title}
          </h2>
          <div className="flex items-center gap-4 m-2">
            <div>
              <Image
                alt="img"
                src={post.img}
                width={0}
                height={0}
                sizes="100vw"
                style={{ width: '30px', height: "30px" }}// Choose the appropriate layout based on your needs
                className="object-cover rounded p-4 md:p-0"
              />
            </div>
            <p className="text-sm">{post.author}</p>
            <p className="text-txt text-sm">
              {formatDateString(post.createdAt)}
            </p>
          </div>
        </div>
        <div></div>
        <div className="content mx-auto flex flex-col lg:flex-row md:mt-2 flex-wrap md:p-4 w-fit">
          <div className="px-4 lg:px-0  text-white flex-wrap text-lg leading-relaxed w-full text-justify text-txt tracking-tight font-primary">
            {
              <Markdown>{post.content}</Markdown>
            }
          </div>
        </div>
      </main>
    </div>
  );
};

export default PostDetail;

我有两个API路线

  1. /api/帖子
import connection from '@/utils/dbConnect';
import Post from '@/models/Posts';
import { NextResponse } from "next/server";


export const GET = async(request)=>
{
    try{
        await connection();
        const posts = await Post.find()        
        return new NextResponse(JSON.stringify(posts), {status: 200, headers: { 'Cache-Control': 'no-store' }});
    }catch(error){
        console.log(error);
        return new NextResponse("Database Error", {status: 400, headers: { 'Cache-Control': 'no-store' }});
    }
}
  1. /api/posts/[slug]
import connection  from '@/utils/dbConnect';
import Post from '@/models/Posts';
import { NextResponse } from "next/server"

export const GET = async(request, {params})=>{

    const {slug} = params
    // fetch data
    try{
        await connection();
        const post = await Post.findOne({slug: slug});
        return new NextResponse(JSON.stringify(post), {status: 200, headers: { 'Cache-Control': 'no-store' }})
    }
    catch(err){
        return new NextResponse("Database Error", {status: 500, headers: { 'Cache-Control': 'no-store' }})
    }
   
}

我有这两个我使用的网址:

NEXT_PUBLIC_BASE_API_URL=https://app-name.vercel.app   (this does not fetch new posts)
NEXT_PUBLIC_BASE_API_URL=http://localhost:3000

当我在 API 中使用本地主机 URL 访问数据库并获取帖子时,它会返回所有新帖子和更新,但是当我使用部署的 URL(.vercel 一个)时,我会获取缓存的数据,并且不会返回新的帖子和更新。数据已获取。

mongodb next.js fetch vercel next-api
1个回答
1
投票

我想你已经认识到这个问题了。 Vercel 对 API 请求使用缓存,因此要获取新的博客文章,您必须等到缓存失效(取决于您为其设置的时间)。

localhost
,数据永远不会被缓存,因此您将始终获得最新的博客文章。

如果您想在新博客文章更新时立即获取它们,您可以将重新验证持续时间设置为

0
,如下所示:

fetch("ENDPOINT", {
  next: {
    revalidate: 0
  }
})

请参阅此文档以了解更多信息:

© www.soinside.com 2019 - 2024. All rights reserved.