通过Firebase Cloud Function调用ChatGPT API时遇CORS错误
问题现象
- 本地Functions模拟器中,前端访问
getSummary函数正常 - 函数部署到云端后,前端(
http://localhost:5173)触发CORS错误 - 控制台直接测试
getSummary函数正常,同时部署的helloWorld函数可正常访问
错误信息
Access to fetch at 'https://us-central1-my-documentation.cloudfunctions.net/getSummary' from origin 'http://localhost:5173' has been 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. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
原因分析
onCall类型的云函数默认会自动处理CORS配置,但如果函数执行过程中出现未捕获的异常(如环境变量缺失、OpenAI API调用失败等),会导致响应未携带CORS头,从而触发浏览器的CORS拦截。
解决方案
1. 确认云端环境变量配置
检查OPEN_API_KEY是否已正确部署到云端:
- 执行命令查看云端配置:
firebase functions:config:get - 若未配置,执行以下命令设置后重新部署:
firebase functions:config:set openai.key="你的OpenAI密钥" firebase deploy --only functions
2. 添加异常捕获与参数验证
修改云函数代码,添加try-catch块捕获异常,并验证输入参数,确保异常情况下返回标准的HttpsError(自动携带CORS头):
import * as functions from "firebase-functions"; import {defineString} from "firebase-functions/v2/params"; import {Configuration, OpenAIApi} from "openai"; const openAIKey = defineString("OPEN_API_KEY"); export const getSummary = functions.https.onCall(async (data, context) => { try { // 验证输入参数合法性 if (!data.prompt || typeof data.prompt !== "string") { throw new functions.https.HttpsError( "invalid-argument", "必须提供有效的prompt字符串" ); } const configuration = new Configuration({ apiKey: openAIKey.value(), }); const openai = new OpenAIApi(configuration); const completion = await openai.createChatCompletion({ model: "gpt-3.5-turbo", messages: [ { role: "user", content: data.prompt, }, ], }); const [choice] = completion.data.choices; return { response: choice.message ?? "no response", }; } catch (error) { // 标准化异常处理 if (error instanceof functions.https.HttpsError) { throw error; } console.error("函数执行错误:", error); throw new functions.https.HttpsError( "internal", "服务器内部错误,请稍后重试" ); } });
3. 前端初始化指定函数区域
确保前端Firebase初始化时明确指定函数部署的区域(us-central1):
import { initializeApp } from "firebase/app"; import { getFunctions, httpsCallable } from "firebase/functions"; const firebaseConfig = { // 你的Firebase项目配置 }; const app = initializeApp(firebaseConfig); // 明确指定函数所在区域 const functions = getFunctions(app, "us-central1"); const getSummary = httpsCallable(functions, "getSummary");
4. 清除浏览器缓存
浏览器缓存的旧响应可能导致CORS问题,清除缓存后重新测试。
内容的提问来源于stack exchange,提问作者user2366158

