Firebase CORS XMLHttpRequest已被阻止问题

时间:2020-04-12 22:46:32

标签: javascript node.js firebase cors google-cloud-functions

我已经查看了几乎所有与Firebase有关的CORS问题有关的StackOverflow问题,但似乎都没有起作用。

我在Firebase上有一些云功能,如果用户通过了身份验证,这些功能会上传图像。我有两个文件:index.jsuser.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);
};

由Firebase网络应用托管的Redux / React中的

前端

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存储设备时,它才会失败。

错误:

CORS策略已阻止从源“ link.firebaseapp.com”访问“ cloudfunction / user / image”处的XMLHttpRequest:请求的资源上没有“ Access-Control-Allow-Origin”标头。

我在做什么错了?

3 个答案:

答案 0 :(得分:1)

根据documentationorigin: true表示原点必须与Origin标头匹配。取而代之的是,您可以使用origin: "*"来允许任何原点,也可以将其保留为空,因为这是默认选项:

const cors = require("cors");
app.use(cors());

答案 1 :(得分:1)

您可以尝试此操作(无提示)

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);

答案 2 :(得分:0)

因此,在经过大量调试并恢复为没有CORS问题的git commit之后,我想我会再次提起遇到此问题的任何人。

我执行了@ariel所说的步骤,但是没有用。原来,当我在functions中初始化firebase应用程序时,出现了一个错误,并注释掉以显示该错误:

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问题,所以对于任何遇到此问题的人来说, ,在提交工作时恢复为提交状态,然后从那里开始是个不错的方法。