遵循文档配置Firebase Functions仍出现CORS策略错误
解决Firebase onCall云函数本地运行的CORS错误
问题说明
我有一个基于Firebase身份验证和Firestore存储的Web应用,按照官方文档用onCall调用云函数,但在localhost运行时碰到CORS错误:
blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
已经给allUsers配置了Cloud Run Invoker权限。
服务端代码
import { onCall, HttpsError } from "firebase-functions/v2/https"; import { onDocumentWritten } from "firebase-functions/v2/firestore"; import * as logger from "firebase-functions/logger"; exports.plusone = onCall({ cors: true, }, (request) => { const email = request.auth?.token.email; const num = request.data.num; logger.log(email + " tried to increase his number by one:" + num); return { finalNum: num + 1, } })
客户端代码
const functions = getFunctions(); const plusone = httpsCallable( functions, 'plusone' ) plusone().then((result) => { console.log(result.data.message) })
解决办法
1. 用本地模拟器运行云函数
本地调试别直接调用线上云函数,用Firebase CLI启动模拟器:
firebase emulators:start --only functions
同时客户端要指向本地模拟器,还要修正调用时的参数和返回值问题:
const functions = getFunctions(); // 连接本地模拟器 connectFunctionsEmulator(functions, "localhost", 5001); const plusone = httpsCallable(functions, 'plusone'); // 必须传num参数,不然服务端会报错;另外服务端返回的是finalNum不是message plusone({ num: 5 }).then((result) => { console.log(result.data.finalNum); }).catch(err => { console.error(err); });
2. 给服务端加参数校验
如果客户端没传num,request.data.num是undefined,执行num+1会抛出错误,导致响应没正确返回CORS头。加个校验:
exports.plusone = onCall({ cors: true, }, (request) => { const email = request.auth?.token.email; const num = request.data.num; // 校验参数类型 if (typeof num !== 'number') { throw new HttpsError('invalid-argument', '必须传入数字类型的num参数'); } logger.log(`${email} tried to increase his number by one: ${num}`); return { finalNum: num + 1, } })
3. 确认权限配置的适用场景
本地模拟器运行时会忽略权限控制,所以allUsers的权限配置只对线上云函数生效。如果是调用线上函数,检查权限是否正确绑定到了对应的云函数服务。
4. 排查浏览器和代理问题
清一下浏览器缓存,或者用无痕模式测试,避免旧缓存干扰。如果开了代理工具(比如Charles),先关掉再试。
内容的提问来源于stack exchange,提问作者Robotic Reaper
相关产品推荐
相关产品推荐

