You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React应用调用Firebase云函数时无法解决CORS错误

解决React + Google Cloud Functions的CORS上传错误

问题背景

已花费3小时尝试解决CORS错误,试过部署网站、修改代理、调整React配置、更改CORS设置等方法,仍未解决。使用create-react-app开发前端,搭配Google Cloud Functions处理图片上传,请求始终触发CORS错误。

前端代码(React)

import './App.css';
import React from 'react';
import axios from 'axios';

function App() {

  const [file, setFile] = React.useState(null);
  function fileSelected(e)
  {
    setFile(()=> e.target.files[0]);
  }
  function uploadFile()
  {
    console.log(file)
    const fd = new FormData();
    fd.append('image', file, file.name)
    axios.post('https://us-central1-athelasapp.cloudfunctions.net/uploadFile', fd)
    .then(res => {
      console.log(res)
    });
  }
  return (
    <div className="App">
      <input type="file" onChange={fileSelected}/>
      <input type="submit" onClick={uploadFile}/>
    </div>
  );
}

export default App;

Google Cloud Functions代码

const functions = require("firebase-functions");
const express = require("express");
const cors = require("cors");
const app = express();
const Busboy = require("busboy");
const os = require("os");
const path = require("path");
const fs = require("fs");

const gcconfig = {
  projectId: "athelasapp",
  keyFilename: "athelasapp-firebase-adminsdk-yojnp-1e9141a009.json",
};

const {Storage} = require("@google-cloud/storage");
const gcs = new Storage(gcconfig);
app.use(cors({origin: true}));

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

app.post("/", (req, res) =>{
  if (req.method !== "POST") {
    return res.status(500).json({
      message: "Method Does Not Work",
    });
  }
  const busboy = new Busboy({headers: req.headers});
  let uploadData = null;

  busboy.on("file", (fieldname, file, filename, encoding, mimetype) =>{
    const filepath = path.joing(os.tmpdir(), filename);
    uploadData = {file: filepath, type: mimetype};
    file.pipe(fs.createWriteStream(filepath));
  });

  busboy.on("finish", ()=>{
    const bucket = gcs.bucket("athelasapp.appspot.com");
    bucket.upload(uploadData.file, {
      uploadType: "media",
      metadata: {
        metadata: {
          contentType: uploadData.type,
        },
      },
    });
  }).then(() => {
    res.status(200).json({
      message: "Method Works!",
    });
  }).catch((err) =>{
    res.status(500).json({
      message: "Method Failed!",
    });
  });
  busboy.end(req.rawBody);
});

问题排查与解决方案

1. 修复后端拼写错误

Cloud Functions代码中path.joing是拼写错误,正确应为path.join。这个错误会导致服务器内部报错,无法返回正确响应,浏览器会将此类错误判定为CORS问题。

2. 修正Promise链绑定错误

busboy.on("finish")回调中,bucket.upload是异步操作,需返回该Promise才能让后续.then/.catch正确捕获结果:

busboy.on("finish", () => {
  const bucket = gcs.bucket("athelasapp.appspot.com");
  // 返回upload的Promise,绑定后续处理逻辑
  return bucket.upload(uploadData.file, {
    uploadType: "media",
    metadata: {
      metadata: {
        contentType: uploadData.type,
      },
    },
  });
}).then(() => {
  res.status(200).json({
    message: "Method Works!",
  });
}).catch((err) => {
  console.error(err); // 打印错误日志便于排查
  res.status(500).json({
    message: "Method Failed!",
    error: err.message
  });
});

3. 优化CORS中间件配置

虽然已添加app.use(cors({origin: true})),可显式指定允许的域名避免泛匹配问题:

// 本地开发用http://localhost:3000,线上替换为实际部署域名
app.use(cors({origin: ["http://localhost:3000", "https://your-deployed-domain.com"]}));

4. 前端添加错误捕获

在axios请求中添加.catch,查看具体错误信息,而非仅依赖浏览器的CORS提示:

axios.post('https://us-central1-athelasapp.cloudfunctions.net/uploadFile', fd)
.then(res => {
  console.log(res)
})
.catch(err => {
  console.error("请求详情错误:", err);
});

5. 配置Google Cloud Storage的CORS规则

若前端需直接访问上传后的文件,需为GCS桶设置CORS规则:

# 先创建cors-config.json文件
echo '[
  {
    "origin": ["http://localhost:3000", "https://your-deployed-domain.com"],
    "method": ["GET", "POST", "PUT"],
    "responseHeader": ["Content-Type"],
    "maxAgeSeconds": 3600
  }
]' > cors-config.json

# 应用规则到桶
gcloud storage buckets update gs://athelasapp.appspot.com --cors-file cors-config.json

6. 重新部署Cloud Functions

修改代码后,重新部署函数生效:

firebase deploy --only functions:uploadFile

内容的提问来源于stack exchange,提问作者Bykaugan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 08:27:12