在Angular中调用Firebase可调用函数时出现CORS错误求助
Firebase可调用函数CORS错误解决方案
问题概述
代码编译正常,但调用Firebase可调用函数时触发CORS拦截错误,提示http://localhost:4200来源被跨域策略阻止,预请求的重定向操作不被允许。找不到functions.rules配置文件,Firebase控制台也无Functions规则设置项;已在firebase.json中配置Hosting重写,尝试用httpsCallableFromURL替代httpsCallable但问题未解决。当前使用AngularFire 7搭配Firebase 9,旧版本文档不适用。
错误信息
Access to fetch at 'https://us-central1-triggerable-functions-project.cloudfunctions.net/addMessage' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request. POST https://us-central1-triggerable-functions-project.cloudfunctions.net/addMessage net::ERR_FAILED ... ERROR Error: Uncaught (in promise): FirebaseError: internal FirebaseError: internal
核心修复方案
1. 修正Angular组件的函数实例获取方式
移除手动初始化的Firebase App和Functions实例,改用AngularFire的依赖注入,确保本地开发时自动连接模拟器:
// app.component.ts import { Component, inject } from '@angular/core'; import { Functions, httpsCallable } from '@angular/fire/functions'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { messageText: string | null = null; private functions = inject(Functions); callMe(messageText: string | null) { console.log("调用云函数:" + messageText); const addMessage = httpsCallable(this.functions, 'addMessage'); addMessage({ text: messageText }) .then((result) => { console.log(result.data) }) .catch(error => { console.error('函数调用失败:', error); }); }; }
2. 修复云函数逻辑错误
当前云函数中使用了未定义的snap变量,导致函数执行失败,间接引发CORS相关错误。修正后的代码:
// index.js(云函数代码) import { initializeApp } from "firebase/app"; import * as functions from "firebase-functions"; import { getFirestore, connectFirestoreEmulator, setDoc, doc } from "firebase/firestore"; const firebaseConfig = { apiKey: "...", authDomain: "triggerable-functions-project.firebaseapp.com", projectId: "triggerable-functions-project", storageBucket: "triggerable-functions-project.appspot.com", messagingSenderId: "...", appId: "..." }; const firebaseApp = initializeApp(firebaseConfig); const db = getFirestore(firebaseApp); connectFirestoreEmulator(db, 'localhost', 8080); export const addMessage = functions.https.onCall(async (data, context) => { try { const original = data.text; if (!original) { throw new functions.https.HttpsError('invalid-argument', '消息文本不能为空'); } const uppercase = original.toUpperCase(); // 写入Firestore示例,可按需调整 const docRef = doc(db, 'messages', Date.now().toString()); await setDoc(docRef, { original, uppercase }); return { uppercase }; } catch (error) { console.error(error); if (error instanceof functions.https.HttpsError) { throw error; } throw new functions.https.HttpsError('internal', '函数执行出错'); } });
3. 调整Hosting重写配置(可选)
若需通过Hosting访问函数,确保重写规则与函数名匹配:
// firebase.json { "hosting": { "rewrites": [ { "source": "/addMessage", "function": "addMessage" } ] } }
4. 启动本地模拟器套件
开发阶段必须运行模拟器,避免直接调用线上函数:
firebase emulators:start --only functions,firestore
关键说明
- Firebase可调用函数无需单独配置CORS规则,官方
onCall函数会自动处理跨域请求,只要函数本身执行正常,CORS响应头会自动生成。 - 本地开发时必须连接模拟器,线上函数默认仅允许已验证的域名访问,localhost需额外配置,但开发阶段用模拟器更高效。
内容的提问来源于stack exchange,提问作者Thomas David Kehoe
相关产品推荐
相关产品推荐

