Firebase CORS XMLHttpRequest была заблокирована проблема - PullRequest
0 голосов
/ 13 апреля 2020

Я рассмотрел почти все проблемы StackOverflow, связанные с проблемой CORS в Firebase, и ни одна из них, похоже, не работает.

У меня есть некоторые облачные функции в Firebase Functions, которые загружают изображение, если пользователь аутентифицирован. У меня есть два файла: index.js и user.js.

Фрагмент из index.js:

const functions = require("firebase-functions");
const FBAuth = require("./util/fbAuth");
const app = require("express")();

const cors = require("cors")({origin: true});
app.use(cors);

// FBAuth gets a bearer token from firebase and authenticates
app.post("/user/image", FBAuth, uploadImage);

exports.api = functions.https.onRequest(app);

Фрагмент из user.js

exports.uploadImage = (req, res) => {
  const BusBoy = require('busboy');
  const path = require('path');
  const os = require('os');
  const fs = require('fs');

  const busboy = new BusBoy({ headers: req.headers });

  let imageToBeUploaded = {};

  busboy.on('file', (fieldname, file, filename, encoding, mimetype) => {
    if (mimetype !== 'image/jpeg' && mimetype !== 'image/png') {
      return res.status(400).json({ error: 'Wrong file type submitted' });
    }

    const filepath = path.join(os.tmpdir(), filename);
    imageToBeUploaded = { filepath, mimetype };
    file.pipe(fs.createWriteStream(filepath));
  });
  busboy.on('finish', () => {
    admin
      .storage()
      .bucket()
      .upload(imageToBeUploaded.filepath, {
        resumable: false,
        metadata: {
          metadata: {
            contentType: imageToBeUploaded.mimetype
          }
        }
      })
      .then(() => {
        const imageUrl = `https://firebasestorage.googleapis.com/v0/b/${
          config.storageBucket
        }/o/${imageFileName}?alt=media`;
        return db.doc(`/users/${req.user.handle}`).update({ imageUrl });
      })
      .then(() => {
        return res.json({ message: 'image uploaded successfully' });
      })
      .catch((err) => {
        console.error(err);
        return res.status(500).json({ error: 'something went wrong' });
      });
  });
  busboy.end(req.rawBody);
};

Frontend в редуксе / React, размещенный на веб-сайте Firebase app:

export const uploadImage = (formData) => (dispatch) => {
  dispatch({ type: LOADING_USER });
  axios
    .post("/user/image", formData)
    .then(() => {
      dispatch(getUserData());
    })
    .catch((err) => console.log(err));
};

Что я пробовал:

Я пытался использовать gsutil cors set cors.json. Проблема в том, что все остальные мои функции работают нормально, только когда я загружаю изображение в хранилище Google, происходит сбой.

Ошибка:

Доступ к XMLHttpRequest в «cloudfunction / user / image» от источника «link.firebaseapp.com» был заблокирован политикой CORS: в запрошенном ресурсе отсутствует заголовок «Access-Control-Allow-Origin».

Что я делаю не так?

Ответы [ 3 ]

1 голос
/ 13 апреля 2020

Вы можете попробовать это (без сердечников)

var allowCrossDomain = function (req, res, next) {

    var allowedOrigins = [
      'http://link.firebaseapp.com',
    ];
    var origin = req.headers.origin;
    if (allowedOrigins.indexOf(origin) > -1) {
      res.setHeader('Access-Control-Allow-Origin', origin);
    }

    res.header('Access-Control-Allow-Origin', '*');
    /* if any specific then : */
    // res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
    // res.header('Access-Control-Allow-Credentials', 'true');
    // res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With, accesstoken, latitude, longitude, source');

    // intercept OPTIONS method
    if ('OPTIONS' == req.method) {
      res.send(200);
    } else {
      next();
    }
};

app.use(allowCrossDomain);
1 голос
/ 13 апреля 2020

Согласно документации , origin: true означает, что источник должен совпадать с заголовком Origin. Вместо этого вы можете разрешить любое происхождение с помощью origin: "*" или просто оставить пустым, поскольку это опция по умолчанию:

const cors = require("cors");
app.use(cors());
0 голосов
/ 13 апреля 2020

Итак, после долгих отладок и возврата к коммиту git, в котором не было проблемы с CORS, я решил упомянуть об этом любому, у кого эта проблема возникнет снова.

Я сделал шаги, которые сказал @ariel, но это не сработало. Оказывается, когда я инициализировал приложение firebase в functions, у меня была ошибка, которую я закомментировал, чтобы показать:

const admin = require("firebase-admin");

admin.initializeApp();
// const serviceAccount = require("../db.json");

// admin.initializeApp({
//   credential: admin.credential.cert(serviceAccount),
//   databaseURL: "https://myurl.firebaseio.com",
// });

const db = admin.firestore();

module.exports = { admin, db };

Честно говоря, я не уверен, почему это раньше не работало, и я не совсем уверен, что это было исправлением, но я больше не получаю проблему с CORS, так что для любого другого, кто получит эту проблему, возврат к коммиту, когда он сработает, и выход из него - хороший способ Начните.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...