Firebase CORS XMLHttpRequest 已被阻止的问题

Posted

技术标签:

【中文标题】Firebase CORS XMLHttpRequest 已被阻止的问题【英文标题】:Firebase CORS XMLHttpRequest has been blocked problem 【发布时间】:2020-07-25 11:58:43 【问题描述】:

我已经查看了 Firebase 关于 CORS 问题的几乎所有 *** 问题,但似乎没有一个有效。

如果用户通过身份验证,我在 Firebase Functions 上有一些云功能可以上传图片。我有两个文件: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。问题是我所有其他功能都可以正常工作,只有当我将图像上传到谷歌存储时它才会失败。

错误:

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

我做错了什么?

【问题讨论】:

这是谷歌云存储/firebase 规则/firebase 的 spark 计划的问题吗? 您能否运行以下命令来查看存储桶的 CORS 配置并发布输出:`gsutil cors get gs://[BUCKET_NAME] @marian.vladoi 这就是结果:["maxAgeSeconds": 3600, "method": ["*"], "origin": ["*"]] 即使我现在已经让它工作了,是否应该将其更改为不同的东西? 【参考方案1】:

根据documentation,origin: true 表示源必须匹配Origin 标头。相反,您可以使用origin: "*" 允许任何来源,或者只留空,因为这是默认选项:

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

【讨论】:

仍然出现同样的错误:Access to XMLHttpRequest at 'cloudfunction/user/image' from origin 'link.firebaseapp.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.【参考方案2】:

你可以试试这个(不带cors)

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

【讨论】:

【参考方案3】:

因此,经过大量调试并恢复到没有 CORS 问题的 git 提交后,我想我会再次向遇到此问题的任何人提及它。

我按照@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 问题,所以对于遇到此问题的其他人,当它工作时恢复到提交并从那里开始是一个很好的方法。

【讨论】:

以上是关于Firebase CORS XMLHttpRequest 已被阻止的问题的主要内容,如果未能解决你的问题,请参考以下文章

发送身份验证承载令牌时出现 Cors 策略错误 - node.js(谷歌云功能)

Firebase 函数的 CORS 政策问题

从 Firebase 托管到 Firebase 功能的请求被 CORS 阻止

由于 CORS 问题,firebase 托管阻止脚本

从被 CORS 阻止的 Firebase 托管代码调用 Firebase 函数

如何在firebase函数中将参数传递给cors