۴۰۴ Not Found! قیمت ها به ۴۰۳ برگشت! به مدت محدود!

بزن بریم!
ثانیه
دقیقه
ساعت
روز
دمتین هستم
5 روز پیش توسط دمتین هستم مطرح شد
7 پاسخ

عدم اجرای عمل fetch در Next.jsدر حالت پروداکشن

سلام وقتتون بخیر
من دارم روی یه پروژه ی نکست کار میکنم ، و پروژم یه بخش داشبورد داره که یوزر میتونه چیزای اکانتشو کم و زیاد کنه ، توی این صفحه تعداد زیادی عمل fetch انجام میشه که اطلاعات رو از ای پی آی خود نکست بگیره و ازش استفاده کنه ، ولی مشکلی که هست اینه که تمام fetch ها روی حالت development به راحتی انجام میشه و هر چند باری که صفحه رو رفرش کنی ، مشکلی براش پیش نمیاد ، ولی وقتی روی حالت production هاست میکنین ، برای بار اول که صفحه رو لود میکنین تمام fetch ها رو انجام میده و دیتا رو به راحتی بر میگردونه ، ولی وقتی صفحه رو رفرش میکنین ، دیگه هیچکدوم از fetch ها رو انجام نمیده و صفحه معلق میمونه
توی اینترنت کلی سرچ زدم ، نکست رو آپدیت کردم ولی جواب نداد
کسی راه حلی داره؟

اینم لاگ کنسولش ( توی 3 مرحله صفحه رفرش شده - مرحله اول تمام fetch ها رو انجام میده - مرحله دوم تعداد از اونا و مرحله سوم هیچکدوم رو انجام نمیده ) :

Fetch failed loading: POST "http://localhost:3000/api/user/get".
Navigated to http://localhost:3000/dashboard
1684-64d23b91a2821a49.js:1 Fetch failed loading: GET "http://localhost:3000/p/undefined?_rsc=1bdos".
1684-64d23b91a2821a49.js:1 Fetch finished loading: GET "http://localhost:3000/?_rsc=1bdos".
GET http://localhost:3000/_next/image?url=https%3A%2F%2Fstatic.profe.app%2Fassets%2Fimages%2Fprofe%2Fpfp%2Fundefined.png&w=32&q=75 404 (Not Found)
8422-b5d0be7cb28641c3.js:1 Fetch finished loading: POST "http://localhost:3000/api/user/get".
8422-b5d0be7cb28641c3.js:1 Fetch finished loading: POST "http://localhost:3000/api/profe/get".
8422-b5d0be7cb28641c3.js:1 Profe {result: 'ok', data: {…}, action: 'get_user_profe'}
8422-b5d0be7cb28641c3.js:1 Fetch finished loading: POST "http://localhost:3000/api/profe/subscription/get".
8422-b5d0be7cb28641c3.js:1 Profe Subscription {result: 'ok', data: {…}, action: 'get_subscription'}
8422-b5d0be7cb28641c3.js:1 Profe Connections {result: 'ok', data: Array(1), action: 'get_all_connections'}
8422-b5d0be7cb28641c3.js:1 Fetch finished loading: POST "http://localhost:3000/api/profe/connection/get_all".
8422-b5d0be7cb28641c3.js:1 Profe Theme {result: 'ok', data: {…}, action: 'get_profe_theme'}

Navigated to http://localhost:3000/dashboard
1684-64d23b91a2821a49.js:1 Fetch finished loading: GET "http://localhost:3000/?_rsc=1bdos".
1684-64d23b91a2821a49.js:1 Fetch failed loading: GET "http://localhost:3000/p/undefined?_rsc=1bdos".
8422-b5d0be7cb28641c3.js:1 Fetch finished loading: POST "http://localhost:3000/api/user/get".
GET http://localhost:3000/_next/image?url=https%3A%2F%2Fstatic.profe.app%2Fassets%2Fimages%2Fprofe%2Fpfp%2Fundefined.png&w=32&q=75 404 (Not Found)
8422-b5d0be7cb28641c3.js:1 Profe {result: 'ok', data: {…}, action: 'get_user_profe'}
8422-b5d0be7cb28641c3.js:1 Fetch finished loading: POST "http://localhost:3000/api/profe/get".
8422-b5d0be7cb28641c3.js:1 Profe Subscription {result: 'ok', data: {…}, action: 'get_subscription'}
8422-b5d0be7cb28641c3.js:1 Fetch finished loading: POST "http://localhost:3000/api/profe/subscription/get".
8422-b5d0be7cb28641c3.js:1 Fetch finished loading: POST "http://localhost:3000/api/profe/connection/get_all".
8422-b5d0be7cb28641c3.js:1 Profe Connections {result: 'ok', data: Array(1), action: 'get_all_connections'}
Fetch failed loading: POST "http://localhost:3000/api/profe/theme/get".

Navigated to http://localhost:3000/dashboard
1684-64d23b91a2821a49.js:1 Fetch failed loading: GET "http://localhost:3000/p/undefined?_rsc=1bdos".
1684-64d23b91a2821a49.js:1 Fetch finished loading: GET "http://localhost:3000/?_rsc=1bdos".
GET http://localhost:3000/_next/image?url=https%3A%2F%2Fstatic.profe.app%2Fassets%2Fimages%2Fprofe%2Fpfp%2Fundefined.png&w=32&q=75 404 (Not Found)
dashboard:1 The resource http://localhost:3000/_next/static/css/99d413d82e7b8cff.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally.
dashboard:1 The resource http://localhost:3000/_next/static/css/5515ed53d064730c.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally.
dashboard:1 The resource http://localhost:3000/_next/static/css/99d413d82e7b8cff.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally.
dashboard:1 The resource http://localhost:3000/_next/static/css/5515ed53d064730c.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally.

ثبت پرسش جدید
electera
@electera 5 روز پیش مطرح شد
0

موضوع اینه که next علاقه زیادی به کش کردن داره! و اگر داده تغییر نداره، از کش استفاده میکنه. نوع کش رو برحسب نیاز مشخص کنین تا مشکلی نداشته باشین. تو ورژن ۱۴ و ۱۵ تغییراتی داشته که براساس اون طبق مستندات تعیین کنید.
تو ۱۵ اینطوریه:

fetch(`https://...`, { cache: 'force-cache' | 'no-store' })
fetch(`https://...`, { next: { revalidate: false | 0 | number } })

این لینک ها رو نگاه کن:
Data Fetching and Caching
fetch


دمتین هستم
تخصص : برنامه نویس
@thematin 5 روز پیش مطرح شد
0

درود بر شما @electera عزیز ❤️
ممنون از راهنماییت ، والا از پارامترای cache و revalidate استفاده کردم ، ولی همچنین لجبازی میکنه 😂
بذار کد رو بفرستم یه نگاه دقیق تری بکنی :

useEffect(() => {
        setLoaded(false)
        const fetchData = cache(async () => {

            const profe_token = localStorage.getItem("profe_token");

            if (profe_token) {
              const getUserByTokenRequest = await fetch("/api/user/get", {
                method: "POST",
                cache: "no-store",
                next: {
                  revalidate: false
                },
                headers: {
                    "Content-Type": "application/json"
                },
                body: JSON.stringify({ token: profe_token }),
              });

              const getUserByTokenResponse = await getUserByTokenRequest.json()

              if (getUserByTokenResponse.result == "ok") {
                const getProfeDataRequest = await fetch(`/api/profe/get`, {
                  method: "POST",
                  cache: "no-store",
                  next: {
                    revalidate: false
                  },
                  headers: {
                      "Content-Type": "application/json"
                  },
                  body: JSON.stringify({
                    profe_creator: getUserByTokenResponse.data.user_id
                  })
                });

                const getProfeDataResponse = await getProfeDataRequest.json()
                console.log("Profe",getProfeDataResponse);
                setProfeData(getProfeDataResponse)

                if (getProfeDataResponse.result == "ok") {

                  const getProfeSubscriptionRequest = await fetch(`/api/profe/subscription/get`, {
                    method: "POST",
                    cache: "no-store",
                    next: {
                      revalidate: false
                    },
                    headers: {
                        "Content-Type": "application/json"
                    },
                    body: JSON.stringify({
                        sub_owner: `${getProfeDataResponse.data.profe_id}`
                    })
                  });
                  const getProfeSubscriptionResponse = await getProfeSubscriptionRequest.json()
                  console.log("Profe Subscription",getProfeSubscriptionResponse);
                  setProfeSubscription(getProfeSubscriptionResponse)

                  const getProfeConnectionsRequest = await fetch(`/api/profe/connection/get_all`, {
                    method: "POST",
                    cache: "no-store",
                    next: {
                      revalidate: false
                    },
                    headers: {
                        "Content-Type": "application/json"
                    },
                    body: JSON.stringify({
                        connection_creator: `${getProfeDataResponse.data.profe_id}`
                    })
                  });
                  const getProfeConnectionsResponse = await getProfeConnectionsRequest.json()
                  console.log("Profe Connections",getProfeConnectionsResponse);
                  setProfeConnections(getProfeConnectionsResponse)

                  const getProfeThemeRequest = await fetch("/api/profe/theme/get", {
                      method: "POST",
                      cache: "no-store",
                      next: {
                        revalidate: false
                      },
                      headers: {
                          "Content-Type": "application/json"
                      },
                      body: JSON.stringify({ theme_id: `${getProfeDataResponse.data.profe_theme}` })
                  });

                  const getProfeThemeResponse = await getProfeThemeRequest.json();
                  console.log("Profe Theme",getProfeThemeResponse);
                  setProfeTheme(getProfeThemeResponse)

                  setLoaded(true)

                }

              }
              else {
                localStorage.removeItem("profe_token")
                window.location.href = "/connect"
              }

            }
        });

        fetchData();
    }, []);

اینجا اول بایستی توکن رو از طریق کوکی کاربر بگیره ، یوزر رو از طریق توکن بگیره و پروف ( به اصطلاح همون اکانت کاربر رو از طریق آیدی یوزر بگیره ) و بعد از گرفتن اطلاعات عمومی پروف ، مابقی موارد رو از طریق آیدی پروف دریافت کنه

حالا این مورد توی حالت development کاملا صحیح و بی مورده ، هر چند باری که URL صفحه رو تغییر بدم یا رفرش کنم بی مورد از اول تمام fetch ها رو انجام میده

حالا روی حالت production فرق میکنه ، بار اول وقتی سرور راه میوفته و صفحه لود میشه fetch میکنه و از دفعه بعد دیگه بیخیال fetch کردن میشه

( حالا من یه مورد دیگه ر و تست کردم ، یه پروژه جدید نکست ایجاد کردم و دقیقا همین روند رو دوباره پیاده سازی کردم :

"use client"

import Image from "next/image";
import styles from "./page.module.css";
import { useEffect } from "react";

export default function Home() {

  const fetchData = async() => {
    const request = await fetch("/api",{
      method: "POST",
      headers: {
        "Content-Type": "application/json"
      },
      body: JSON.stringify({
        token: "KIlnd88n3TTFEIK8nH2MswNwHmrPVEqR"
      }),
    })
    const response = await request.json()

    console.log(response);

  }

  useEffect(() => {
    fetchData()
  },[])

  return (
    <>
    Hello
    </>
  );
}

و همون روت ای پی آی پروژه قبلی ، اما اینبار روی پروداکشن هر رفرش یه دور fetch میکنه


دمتین هستم
تخصص : برنامه نویس
@thematin 5 روز پیش مطرح شد
0

البته اون خط کد که :

        const fetchData = cache(async () => {

رو فراموش کن اینجاش cache رو یادم رفت بردارم

و اینکه جالبی ماجرا اینه که توی بار دوم که fetch میکنه مثلا اون fetch اولی و دومی رو انجام میده بعد دیگه بقیه ش رو انجام نمیده

یا مثلا یادمه یه بار توی رفرش دوم مجدد fetch ها رو انجام داد یکی دو تای آخری رو انجام نداد


electera
@electera 5 روز پیش مطرح شد
0

بنظرم مشکل از fetch یا cache نیست. کداتون اصولی نیست!
شما همه چیرو گذاشتی توی useEeffect و چندتا کار رو یکجا داری انجام میدی! چرا؟؟
بررسی توکن رو تو یک middleware تعریف کن که هر روتی نیاز داشت، راحت چکش کنی
علاوه بر اون شما داری از localStorage استفاده میکنی که امنیتش از کوکی و سشن بیشتره و میتونی نام کاربری، ایمیل یا شماره تلفن و حتی تم رو اونجا ذخیره کنی که نیاز نباشه مدام درخواست بفرستی و اینجوری فقط موقع درخواست از سرور بررسی کن توکن معتبره یا نه.
در نظر بگیر که useEffect بعداز رندر کامل کامپوننت اجرا میشه و باید درجای درست ازش استفاده کنی، بنظرم چندتا مقاله در مورد useEffect مطالعه کن. من خودم خیلی کم از useEffect استفاده میکنم و البته اگر روکرد اصولی باشه نیازی به استفادش نیست!!
سمپل های زیادی هست برای احراز هویت و.. هست مخصوصاً گیت هاب، نگاهی بنداز، میتونه بهت ایده بده.


دمتین هستم
تخصص : برنامه نویس
@thematin 5 روز پیش مطرح شد
0

سلام @electera عزیز
مرسی از پیشنهادات و پاسخت ❤️
والا دروغت نگم خیلی حرفه ای توی Next.js فعالیت نداشتم ، بیشتر تمرکزم رو این بود که اول پروژمو به یه سرانجام برسونم و بعدش با یادگیری یه سری از نکات مثل Middlewere و Authentication و چیزای مهم دیگه به زمانش یاد بگیرم
بعد اینکه در مورد موضوع useEffect ، والا برنامم این بود که توی فایل layout.js که قبل کامپوننت کلاینت قراره اجرا شه ، کار fetch رو انجام بدم و مقادیر رو پاس بدم به page.js که کامپوننت کلاینتم هست ، و اونجا ازش استفاده کنم ، ولی مشکل گرفتن توکن از داخل localStorage رو داشتم ، چرا که سرور کامپوننت فکر نکنم localStorage رو ساپورت کنه ، سر همین کار گرفتن دیتا رو از طریق localStorage و پاس دادن اون به api برای گرفتن دیتا انجام میدم
و تا چند روز پیش عملکرد fetch کردن خیلی خوب داشت کار میکرد ، اینکه راحت دیتا رو میگرفت و میشد ازش استفاده کرد ، از امروز اینجوری شده
اگر در مورد کش شدن دیتا ایده ای داری که یه جوری ردش کنم و بتونم توی هر بار لود ، دیتا رو با fetch بگیرم که ممنون میشم
برای پیشنهادات بالا هم ازت ممنونم ، کارسازه ❤️❤️❤️


دمتین هستم
تخصص : برنامه نویس
@thematin 5 روز پیش مطرح شد
0

یعنی برای گرفتن و قرار دادن اطلاعات کاربر میتونم به جای fetch های طولانی و تعداد بالا داخل کامپوننت از middleware استفاده کنم؟


electera
@electera 3 روز پیش مطرح شد
0

آره راهش همونه. از اونجایی که تو نکست روتها اسم فولدرها هستن، تو لایوت middleware رو باید تعریف کنی.
توکن رو داخل کوکی بریزی بهتره، میتونی تاریخ انقضا بزاری و با رفرش توکن بروزش کنی. برای اینکه راحت بتونی state های مختلف رو بین کامپوننت ها به اشتراک بزاری از contex یا ریداکس استفاده کن که بنظرم همون useContex جواب کارتو میده.
در مورد کش شدن دیتا همونطور که گفتم بنظرم مشکل از fetch نیست، پیشنهاد میکنم ریکت رو عمیقتر مطالعه کنی و برای هر ابزاری که استفاده میکنی درمورش مقاله ها و مستنداتش رو مطالعه کنی مخصوصاً هوک ها.
در واقع احراز هویت و سطح دسترسی و خیلی موضوعات پایه رو نباید تو نکست زیاد درگیرش باشی!! بیشتر درگیری باید برای پیاده سازیش باشه و بهتره در ریکت حلش کنی چون اونجا به نسبت راحتتره و کلی سمپل براش هست.


برای ارسال پاسخ لازم است وارد شده یا ثبت‌نام کنید

ورود یا ثبت‌نام