#firebase #google-cloud-functions #next.js #firebase-hosting
#firebase #google-cloud-функции #next.js #firebase-хостинг
Вопрос:
Я начал создавать API с использованием NextJS framework. Я хочу, чтобы оно было размещено на Firebase (хостинг и функции). Все работает, пока я отправляю только запросы GET. Когда я отправляю POST-запрос, я получаю сообщение об ошибке «502 Bad Gateway».
Это очень просто воспроизвести. Вам просто нужно загрузить и развернуть пример, предоставленный командой разработчиков NextJS.
-
создайте новый проект в Firebase console
-
установите пример «с хостингом Firebase«
-
измените название проекта в .файл firebaserc (строка 3)
-
создайте папку «api» в папке «страницы»
-
создайте файл «hello.js « в папке «api» и добавьте следующий фрагмент
export default async (req, res) => { const { body, method } = req; console.log("method :>> ", method); console.log("body :>> ", body); switch (method) { case "POST": res.status(200).end(`Method ${method} supported!`); break; default: res.setHeader("Allow", ["POST"]); res.status(405).end(`Method ${method} Not Allowed`); } };
-
разверните приложение
-
отправьте запрос GET на «https: // [project-name].web.app / api / hello» и посмотрите, как это работает
-
отправьте запрос POST на «https: // [project-name].web.app / api / hello» и увидите, что он не работает
У вас такая же ошибка, как у меня?
Я потратил 2 дня на чтение статей, просмотр видео и пробование разных конфигураций. Вы даже можете обновить функции firebaseFunctions, чтобы добавить a console.log
и увидеть, что запрос POST перехватывается облачной функцией Firebase, но сервер NextJS не передает его в наш API, как для запроса GET. Это выходит за рамки моих навыков…
Ниже вывод, который у вас должен быть. На запрос POST следует ответить 200 - Method POST is supported!
.
Комментарии:
1. У меня есть другой проект, использующий ExpressJS, и я никогда не сталкивался с этой проблемой.
2. Я склонен думать, что это вызвано
res.status(204).end(``Method ${method} supported!``);
не чем иным. Попробуйтеres.status(204).end();
вместо этого.3. @samthecodingman Если вы попробуете, вы увидите, что в облачных функциях Firebase нет журнала. Это означает, что метод не вызывается. Я обновил фрагмент (спасибо за помощь!)
Ответ №1:
Это было настоящей проблемой для отслеживания, но, покопавшись некоторое время, я обнаружил, что одна и та же проблема возникает для запросов PUT и PATCH. Что предполагает, что это как-то связано с телом запроса. К сожалению, узнав об этом, я наткнулся на ветку проблемы # 7960, где они обнаружили ту же проблему.
Проще говоря, тело запроса обрабатывается один раз, https.onRequest()
а затем nextjsHandle()
пытается проанализировать его снова. Поскольку тело уже было обработано, raw-body
модуль (внутри nextjsHandle()
) бесконечно ожидает 'data'
событий, которые никогда не наступят.
В настоящее время нет способа отключить синтаксический анализ тела, выполняемый https.onRequest()
, поэтому он должен быть отключен на next.js конец. К сожалению, нет глобального выключателя для синтаксического анализа тела, который можно добавить, next.config.js
и это должно быть сделано для каждого маршрута API (файлов pages/api
) (который может измениться, если будет добавлено предлагаемое исправление в PR # 16169).
Чтобы отключить синтаксический анализ тела для данного маршрута, вы добавляете следующее в файл маршрута
export const config = {
api: {
// disables call to body parsing module
bodyParser: false,
}
};
Однако, как упоминалось в выпуске # 7960 от @rscotten, вы также можете захотеть использовать next dev
его при разработке своего приложения, поэтому вам нужно включить его во время использования next dev
, но отключить во время развертывания. Это можно сделать с помощью
export const config = {
api: {
// disables call to body parsing module while deployed
bodyParser: process.env.NODE_ENV !== 'production',
}
};
Применение этих изменений к hello.js
дает:
export default async (req, res) => {
const {
body,
method
} = req;
console.log("method :>> ", method);
console.log("body :>> ", body);
switch (method) {
case "POST":
res.status(200).end(`Method ${method} supported!`);
break;
default:
res.setHeader("Allow", ["POST"]);
res.status(405).end(`Method ${method} Not Allowed`);
}
};
export const config = {
api: {
// disable nextjs's body parser while deployed
// (as body parsing is handled by `https.onRequest()`),
// but enable it for local development using `next dev`
bodyParser: process.env.NODE_ENV !== 'production',
}
};
Комментарии:
1. Я искал неправильный путь. У меня уже была такая же проблема с приложением ExpressJS, но ошибка, которую я получил, была ясной, я мог быстро ее решить. Я начал заменять NextJS на ExpressJS, когда увидел ваш ответ. Большое спасибо, Сэм, за вашу помощь!
2. Также должна быть проблема с конфигурацией хостинга Firebase. Потому что теперь у меня «502 Bad Gateway» при использовании Puppeteer в облачных функциях Firebase. Метод «goto» не завершается. Локально все работает нормально, и в другом проекте я могу использовать Puppeteer без каких-либо проблем. Разница в том, что я перенаправляю не все запросы на сервер Next / Express, а только те, которые находятся в разделе «/ api / **». Я расследую это…
3. Я был неправ, но вместо удаления моего комментария давайте сохраним историю того, что произошло после проблемы со шлюзом сервера Express / Next. Я использую Puppeteer в API, который я предоставляю через сервер. Я все еще получал
502 - Bad Gateway
сообщение об ошибке, потому что после того, как Puppeteer загрузил страницу, она ждала слишком долго. Я просто удаляю «дополнительный»waitForNavigation
вызов. Локально с этим проблем не было, но на Firebase это мешало продолжению моего скрипта.