Как включить cors в функциях firebase

#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. Единственное отличие от того, что я пробовал, от того, что вы показываете, — это асинхронность, которая не должна иметь значения?