Вопрос или проблема
Привет всем, спасибо за прочтение
У меня небольшая проблема с проектом цитат, использующим nextjs, развернутом на Vercel. На локальном компьютере всё работает хорошо, но на развернутом варианте не появляются новые цитаты.
Всегда показывается один и тот же результат, у меня нет идей, что может быть не так, мне нужен совет.
Вот мой /api
import axios from "axios";
import { NextResponse } from "next/server";
import { Quotable, QuoteTypes, QuoteZen } from "@/types/quotesType";
const urlWaifu = "https://waifu.it/api/v4/quote";
const urlZen = "https://zenquotes.io/api/random/";
const urlQuotable =
"https://api.quotable.io/quotes/random?limit=1&tags=technology|famous-quotes|film|love|pain|sadness|self-help";
const list = ["Zen", "Waifu", "Quotable"];
const randomizer = Math.floor(Math.random() * list.length);
const selected = list[randomizer];
export async function GET() {
try {
let response;
let provider;
let linkProvider;
switch (selected) {
case "Waifu":
provider = "Waifu.it";
linkProvider = "https://waifu.it/";
response = await axios.get(urlWaifu, {
headers: {
Authorization: process.env.WAIFU_IT_TOKEN,
},
});
break;
case "Zen":
provider = "ZenQuotes";
linkProvider = "https://zenquotes.io/";
const resZ = await axios.get(urlZen);
const zenQuotes: QuoteZen = resZ.data[0];
const readyZenQuotes: QuoteTypes = {
_id: 1,
quote: zenQuotes.q,
anime: "",
author: zenQuotes.a,
};
response = { data: readyZenQuotes };
break;
case "Quotable":
provider = "Quotable Quotes";
linkProvider = "https://github.com/lukePeavey/quotable";
const resQ = await axios.get(urlQuotable);
const QuotableQuotes: Quotable = resQ.data[0];
const readyQuotableQuotes: QuoteTypes = {
_id: QuotableQuotes._id,
quote: QuotableQuotes.content,
anime: "",
author: QuotableQuotes.author,
};
response = { data: readyQuotableQuotes };
break;
}
return NextResponse.json(
{ data: response?.data, provider: provider, linkProvider: linkProvider },
{
status: 200,
headers: {
"Cache-Control":
"no-store, no-cache, must-revalidate, proxy-revalidate",
Pragma: "no-cache",
Expires: "0",
"Surrogate-Control": "no-store",
},
}
);
} catch (error: any) {
return NextResponse.json(
{ error: "Ошибка при получении цитат", details: error.message || error },
{ status: 500 }
);
}
}
Затем я запрашиваю это так
const fetchQuote = async () => {
try {
setIsLoading(true);
const response = await fetch(`/api/quotes`, {
cache: "no-store",
});
if (!response.ok) {
throw new Error(`HTTP ошибка! статус: ${response.status}`);
}
const rawData = await response.json();
const quotesData = rawData.data;
setQuote(quotesData);
setProvider(rawData.provider);
setLinkProvider(rawData.linkProvider);
setIsLoading(false);
} catch (error) {
setIsError(true);
toast.error("Ошибка при получении мудрости. Пожалуйста, попробуйте снова.");
}
};
fetchQuote не получает больше одной цитаты. Приложение загружает её только один раз, когда fetchQuote вызывается снова, оно показывает те же данные, что и раньше.
Ожидается, что оно должно получать другие данные/цитаты.
На всякий случай я прикрепляю ссылку на репозиторий здесь
Репозиторий
Спасибо заранее
Ответ или решение
Проблема с получением новых цитат из API на Vercel
Здравствуйте!
Я рад помочь вам решить проблему, с которой вы столкнулись при развертывании вашего проекта на Vercel с использованием Next.js. Основная проблема, кажется, заключается в том, что ваше приложение не получает новые цитаты при повторном вызове API. Давайте разберёмся с вашей реализацией и возможными решениями.
1. Описание проблемы
Вы указали, что при вызове функции fetchQuote
к API /api/quotes
, приложение загружает данные только один раз, а при повторных вызовах возвращает те же данные. Это может означать, что API кеширует ответ или сам API-провайдер не предоставляет новые данные при каждом запросе.
2. Анализ кода
Ваш код для API выглядит корректно и стильно написан. Основные компоненты включают:
- Вызов API через библиотеки Axios для получения случайных цитат.
- Случайный выбор источника цитат (Waifu, Zen, Quotable).
Ваша функция GET
возвращает данные с установленными заголовками управления кешированием:
"Cache-Control": "no-store, no-cache, must-revalidate, proxy-revalidate",
Pragma: "no-cache",
Expires: "0",
Эти заголовки должны предотвращать кеширование. Если после повторного вызова всё равно возвращаются те же данные, то проблема может быть не в вашем коде, а в источнике цитат.
3. Возможные причины проблемы
-
Кеширование на уровне API: Некоторые API могут кешировать ответы, если они предполагают, что данные не меняются часто. В этом случае, если вы делаете несколько запросов за короткий период времени, API может возвращать одно и то же значение.
-
Ранее загруженные данные в браузере: Если браузер кеширует ответ от API, то даже с установленными заголовками, он может не выполнять новый запрос, а возвращать закешированные данные.
-
Случайный выбор цитат: Поскольку выбор источника цитат случайный, он может вести себя так, что в некоторых случаях только один источник активно предоставляет данные.
4. Рекомендации по решению проблемы
Вот несколько рекомендаций для устранения вашей проблемы:
-
Добавление параметров запроса: Вы можете добавить временную метку или случайный параметр к URL запроса в функции
fetchQuote
, чтобы принудить браузер и API выполнить новый запрос:const response = await fetch(`/api/quotes?timestamp=${new Date().getTime()}`, { cache: "no-store", });
-
Проверка источников API: Убедитесь, что каждый из указанных вами API действительно возвращает уникальные данные при каждом запросе. Возможно, стоит протестировать каждый из них отдельно, чтобы увидеть, поведение каждого из них.
-
Логирование запросов: Включите логирование в вашем API, чтобы видеть, сколько раз был вызван метод и возвращает ли он одни и те же данные.
-
Ограничение кеширования на стороне клиента: Вы уже используете
cache: "no-store"
при запросе, что хорошо. Убедитесь, что это применяется во всех точках вашего приложения.
5. Заключение
Ваше приложение на Vercel с Next.js является отличным примером для работы с API, и я уверен, что предложенные изменения помогут вам решить проблему повторного получения данных. Не стесняйтесь экспериментировать с различными подходами к кешированию, чтобы определить, что именно вызывает ваше затруднение. Желаю удачи, и если у вас появится больше вопросов, не стесняйтесь обращаться за помощью!