#typescript #firebase #google-cloud-functions #cors
# #typescript #firebase #google-cloud-функции #cors
Вопрос:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const inventory_functions = require("firebase-functions");
const inventory_admin = require("firebase-admin");
import * as cors from "cors";
const corsHandler = cors({ origin: true });
exports.getByLocation = inventory_functions.https.onRequest(
(request, response) => {
corsHandler(request, response, async () => {
const inventory = await inventory_admin
.firestore()
.collection("inventory")
.get();
response.status(200).send(JSON.stringify(inventory));
});
}
);
Вот как я пытаюсь получить доступ из клиента:
const res = await fetch(
"https://us-central1-surplus-functions.cloudfunctions.net/inventory-getByLocation"
);
if (!res.ok) throw new Error(res.statusText);
return res.json();
Вот ошибка:
Доступ к выборке осуществляется по адресу ‘https://[идентификатор проекта].cloudfunctions.net/inventory-getByLocation » из источника «http://localhost:3000 ‘ был заблокирован политикой CORS: на запрошенном ресурсе отсутствует заголовок ‘Access-Control-Allow-Origin’. Если непрозрачный ответ соответствует вашим потребностям, установите режим запроса на «no-cors», чтобы получить ресурс с отключенным CORS.
Я проверил, что я не вижу заголовков ответов в postman, которые я ожидаю, хотя я устанавливаю их в приведенном выше коде, поэтому я не понимаю, почему это так.
Теперь у меня есть рабочее решение:
const authentication_cors = require("cors")({
origin: true,
});
exports.register = authentication_functions.https.onRequest(
async (request: any, response: any) => {
return authentication_cors(request, response, async () => {
const data = JSON.parse(request.body);
const resp = await AuthenticationBO.Register(
authentication_admin,
data.Profile.Email,
data.Vendor,
data.Profile,
data.Vendor?.Name
);
response.send(resp);
});
});
Комментарии:
1. вы нашли решение, так как у меня тоже возникли проблемы с CORS.
2. @Jag99 Я добавил рабочее решение выше
Ответ №1:
Вы можете использовать документацию, на которую ссылается @Paul Huynh, но сделать небольшую адаптацию для ее использования в функциях Firebase:
exports.getByLocation = inventory_functions.https.onRequest((req, res) => {
// Set CORS headers for preflight requests
// Allows GETs from any origin with the Content-Type header
// and caches preflight response for 3600s
res.set('Access-Control-Allow-Origin', '*');
if (req.method === 'OPTIONS') {
// Send response to OPTIONS requests
res.set('Access-Control-Allow-Methods', 'GET');
res.set('Access-Control-Allow-Headers', 'Content-Type');
res.set('Access-Control-Max-Age', '3600');
res.status(204).send('');
} else {
// Do whatever your function has to do
const inventory = await inventory_admin
.firestore()
.collection("inventory")
.get();
response.status(200).send(JSON.stringify(inventory));
}
};
Если вы хотите реализовать express, вы можете включить CORS более элегантным способом, следуя этому документу
Комментарии:
1. Удалось ли вам успешно вызвать эту функцию из браузера? Если да, не могли бы вы поделиться тем, как вы сделали запрос?
2. Я смог успешно вызвать вашу функцию
await fetch( "https://[project-id].cloudfunctions.net/inventory-getByLocation")
с помощью консоли Chrome. Кстати, вы не должны публиковать свой идентификатор проекта публично, я предлагаю вам отредактировать все места, в которых вы им поделились
Ответ №2:
Я столкнулся с этим только вчера. В документации по облачным функциям Google есть раздел об этом. Вот как они это сделали. Я тоже успешно использовал этот код. Вы можете установить Allow-Origin
значение *
exports.corsEnabledFunctionAuth = (req, res) => {
// Set CORS headers for preflight requests
// Allows GETs from origin https://example.com with Authorization header
res.set('Access-Control-Allow-Origin', 'https://example.com');
res.set('Access-Control-Allow-Credentials', 'true');
if (req.method === 'OPTIONS') {
// Send response to OPTIONS requests
res.set('Access-Control-Allow-Methods', 'GET');
res.set('Access-Control-Allow-Headers', 'Authorization');
res.set('Access-Control-Max-Age', '3600');
res.status(204).send('');
} else {
res.send('Hello World!');
}
};
Комментарии:
1. Значит, вы не используете «functions.https.onRequest»? Как выглядит ваш запрос от клиента?
2. Также вы видите, что заголовки возвращаются в ответ, как и ожидалось, через postman или что-то еще?
3. Единственное отличие от того, что я пробовал, от того, что вы показываете, — это асинхронность, которая не должна иметь значения?