Включение CORS в облачных функциях для Firebase
В настоящее время я изучаю, как использовать новые функции Cloud для Firebase, и проблема, с которой я сталкиваюсь, заключается в том, что я не могу получить доступ к функции, которую я написал через запрос AJAX. Я получаю ошибку "Нет" Access-Control-Allow-Origin ". Вот пример функции, которую я написал:
exports.test = functions.https.onRequest((request, response) => {
response.status(500).send({test: 'Testing functions'});
})
Функция находится в этом URL:
https://us-central1-fba-shipper-140ae.cloudfunctions.net/test
Firebase docs предлагает добавить промежуточное ПО CORS внутри функции, я пробовал, но он не работает для меня: https://firebase.google.com/docs/functions/http-events p >
Вот как я это сделал:
var cors = require('cors');
exports.test = functions.https.onRequest((request, response) => {
cors(request, response, () => {
response.status(500).send({test: 'Testing functions'});
})
})
Что я делаю неправильно? Я был бы признателен за любую помощь в этом.
UPDATE:
Даг Стивенсон помог. Добавление ({origin: true}) устранило проблему, мне также пришлось изменить response.status(500)
на response.status(200)
, который я полностью пропустил вначале.
Ответы
Ответ 1
Существуют две примеры функций, предоставленные командой Firebase, которые демонстрируют использование CORS:
Во втором примере используется другой способ работы с cors, чем вы в настоящее время используете.
Кроме того, рассмотрите импортирование, подобное этому, как показано в примерах:
const cors = require('cors')({origin: true});
Ответ 2
Вы можете установить CORS в облачной функции следующим образом: response.set('Access-Control-Allow-Origin', '*');
Нет необходимости импортировать пакет cors
Ответ 3
Для тех, кто пытается сделать это в Typescript, это код:
import * as cors from 'cors';
const corsHandler = cors({origin: true});
export const exampleFunction= functions.https.onRequest(async (request, response) => {
corsHandler(request, response, () => {});
//Your code here
});
Ответ 4
Один дополнительный фрагмент информации, только ради того, чтобы зайти через это через некоторое время:
Если вы используете хостинг firebase, вы также можете настроить перезаписи, чтобы, например, URL-адрес (firebase_hosting_host)/api/myfunction перенаправлялся на функцию (firebase_cloudfunctions_host)/doStuff. Таким образом, поскольку перенаправление прозрачное и серверное, вам не нужно иметь дело с cors.
Вы можете установить это с помощью раздела перезаписи в файле firebase.json:
"rewrites": [
{ "source": "/api/myFunction", "function": "doStuff" }
]
Ответ 5
У меня есть небольшое дополнение к @Andreys, отвечающему на его собственный вопрос.
Кажется, вам не нужно вызывать обратный вызов в функции cors(req, res, cb)
, поэтому вы можете просто вызвать модуль cors в верхней части своей функции, не вставляя весь свой код в обратный вызов. Это намного быстрее, если вы захотите впоследствии реализовать корс.
exports.exampleFunction = functions.https.onRequest((request, response) => {
cors(request, response, () => {});
return response.send("Hello from Firebase!");
});
Не забывайте инициализировать корс, как указано в открытии сообщения:
const cors = require('cors')({origin: true});
Ответ 6
Никакие решения CORS не работали для меня... до сих пор!
Не уверен, сталкивался ли кто-нибудь еще с той же проблемой, что и я, но я настроил CORS, как 5 разных способов по сравнению с примерами, которые я нашел, и ничего не получалось. Я создал минимальный пример с Plunker, чтобы увидеть, действительно ли это было ошибкой, но пример прошел прекрасно. Я решил проверить журналы функций firebase (найденные в консоли firebase), чтобы узнать, может ли это сказать мне что-нибудь. У меня была пара ошибок в моем коде сервера узлов, не связанных с CORS, которые, когда я отлаживал, освободили меня от моего сообщения об ошибке CORS. Я не знаю, почему ошибки кода, не связанные с CORS, возвращают ответ об ошибке CORS, но это привело меня к неправильной кроличьей норе на целое количество часов...
tl; dr - проверяет ваши журналы Firebase-функций, если не работают решения CORS, и отлаживает любые ваши ошибки
Ответ 7
Я только что опубликовал небольшой фрагмент:
https://mhaligowski.github.io/blog/2017/03/10/cors-in-cloud-functions.html
Как правило, вы должны использовать Express пакет CORS, что требует небольшого взлома, чтобы соответствовать требованиям в функциях GCF/Firebase.
Надеюсь, что это поможет!
Ответ 8
Для чего это стоило у меня onRequest
такая же проблема при передаче app
в onRequest
. Я понял, что проблема заключалась в косой черте в URL запроса для функции firebase. Express искал '/'
но у меня не было косой черты в функции [project-id].cloudfunctions.net/[function-name]
. Ошибка CORS была ложноотрицательной. Когда я добавил косую черту, я получил ожидаемый ответ.
Ответ 9
Только этот способ работает для меня, так как у меня есть авторизация в моем запросе:
exports.hello = functions.https.onRequest((request, response) => {
response.set('Access-Control-Allow-Origin', '*');
response.set('Access-Control-Allow-Credentials', 'true'); // vital
if (request.method === 'OPTIONS') {
// Send response to OPTIONS requests
response.set('Access-Control-Allow-Methods', 'GET');
response.set('Access-Control-Allow-Headers', 'Content-Type');
response.set('Access-Control-Max-Age', '3600');
response.status(204).send('');
} else {
const params = request.body;
const html = 'some html';
response.send(html)
} )};
Ответ 10
Это может быть полезно. Я создал Firebase HTTP функцию облака с экспресс (пользовательский URL)
const express = require('express');
const bodyParser = require('body-parser');
const cors = require("cors");
const app = express();
const main = express();
app.post('/endpoint', (req, res) => {
// code here
})
app.use(cors({ origin: true }));
main.use(cors({ origin: true }));
main.use('/api/v1', app);
main.use(bodyParser.json());
main.use(bodyParser.urlencoded({ extended: false }));
module.exports.functionName = functions.https.onRequest(main);
Пожалуйста, убедитесь, что вы добавили переписать разделы
"rewrites": [
{
"source": "/api/v1/**",
"function": "functionName"
}
]
Ответ 11
Если вы не используете Express или просто хотите использовать CORS. Следующий код поможет решить
const cors = require('cors')({ origin: true, });
exports.yourfunction = functions.https.onRequest((request, response) => {
return cors(request, response, () => {
// *Your code*
});
});
Ответ 12
Если есть такие люди, как я: если вы хотите вызвать облачную функцию из того же проекта, что и сама облачная функция, вы можете запустить firebase sdk и использовать метод onCall. Он будет обрабатывать все для вас:
exports.newRequest = functions.https.onCall((data, context) => {
console.log('This is the received data: ${data}.');
return data;
})
Вызовите эту функцию следующим образом:
// Init the firebase SDK first
const functions = firebase.functions();
const addMessage = functions.httpsCallable('newRequest');
Документы Firebase: https://firebase.google.com/docs/functions/callable
Если вы не можете инициировать SDK, вот суть из других предложений: