У меня возникли проблемы с обработкой (индивидуальной) ошибки 404 с помощью хостинга и функций Firebase. Ниже приведен упрощенный код, который без проблем работает на локальном хосте.
Однако, похоже, возникла проблема с обработкой ошибки 404 при ее развертывании. Хостинг Firebase возвращает 500 вместо 404.
https://xxxx.web.app/myfunction/hello
-> возвращает «привет, мир»https://xxxx.web.app/myfunction/404
-> возвращает ошибку 500http://localhost/myfunction/404
-> возврат (по индивидуальному заказу) 404Кто-нибудь знает, что с этим не так?
index.js
const functions = require('firebase-functions');
exports.myfunction = functions.region('asia-east1').runWith({maxInstances: 2}).https.onRequest((request, response) => {
if (request.path == '/myfunction/hello') {
return response.send("hello world")
}
response.set('X-Cascade', 'PASS');
return response.status(404).end()
});
Firebase.json
{
"functions": [
{
"source": "functions",
"codebase": "default",
"ignore": [
"node_modules",
".git",
"firebase-debug.log",
"firebase-debug.*.log"
]
}
],
"hosting": {
"public": "public",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "/myfunction/*",
"function": "myfunction",
"region": "asia-east1"
}
]
}
}
редактировать: Основная структура файла выглядит примерно так:
.
├── firebase.json
├── functions
│ ├── index.js
│ └── package.json
└── public
├── 404.html
└── index.html
Да, у меня есть файл 404.html в общей папке.
Функции Firebase и хостинг Firebase работают в совершенно разных средах во время производства, поэтому файл 404.html
в папке public
будет применяться только тогда, когда браузер запускает 404 Not Found error
, а НЕ функцию Firebase, которая находится на стороне сервера, как видно из документации .
Это отличается от использования локального эмулятора, поскольку эмулятор функций имеет доступ к файлам, поэтому он работает локально.
Из вашего кода у вас есть два варианта.
Опция 1
Вы можете создать собственный 404.html
внутри каталога functions
и отправить его в браузер, как показано ниже.
Примечание: я удалил X-Cascade
, потому что в этом нет необходимости и это вызовет 500 error
, как вы описали.
const functions = require('firebase-functions');
exports.myfunction = functions
.region('asia-east1')
.runWith({ maxInstances: 2 })
.https.onRequest((request, response) => {
if (request.path == '/myfunction/hello') {
return response.send('hello world');
}
return response.status(404).sendFile('404.html', { root: __dirname });
});
Вариант 2
Более простой способ — указать маршрут в вашем firebase.json
.
"hosting": {
"public": "public",
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
"rewrites": [
{
"source": "/myfunction/hello",
"function": "myfunction",
"region": "asia-east1"
}
],
},
Затем в вашей облачной функции:
const functions = require('firebase-functions');
exports.myfunction = functions
.region('asia-east1')
.runWith({ maxInstances: 2 })
.https.onRequest((request, response) => {
return response.send('hello world');
});
Спасибо, я бы придерживался варианта 1, так как функция делает больше :) Я думал, что добавление X-Cascade
вернет обработку маршрута на хостинг, но, похоже, это не тот случай, я думаю?
Функция Firebase работает в среде, отличной от хостинга Firebase, поэтому она не будет работать.
У вас есть значок
404.html
в общей папке?