简体   繁体   English

Firebase 可调用云 Function CORS 错误使用 Z035489FF8D092741943E4A83241F5

[英]Firebase Callable Cloud Function CORS Error using Firebase Emulator and Vite

The following is the client-side code to call the cloud function:下面是调用云function的客户端代码

// add a new post
addPostForm.addEventListener('click', (e) => {
  e.preventDefault();
  
  const addPost = httpsCallable(functions, 'addPost');
  addPost({
    title: addPostForm.postTitle.value,
    description: addPostForm.postDescription.value,
  })
  .then(() => {
    addPostForm.reset(),
    addPostModal.classList.remove('open');
    addPostForm.querySelector('.error').textContent = '';
  })
  .catch(error => {
    addPostForm.querySelector('.error').textContent = error.message;
  })
});

The cloud function:云function:

exports.addPost = functions.https.onCall((data, context) => {
    if(!context.auth){
        throw new functions.https.HttpsError(
            'unauthenticated',
            'only authenticated users can post'
        );
    }
    if(data.text.length > 140){
        throw new functions.https.HttpsError(
            'invalid-argument',
            'description must be no more than 140 characters long'
        );
    }
    return admin.firestore().collection('Posts').add({
        title: data.title,
        description: data.description,
        likes: '',
        bookmarks: '',
    });
});

Firebase Setup: Firebase 设置:

import { initializeApp, getApp } from "firebase/app";
import { getAuth, connectAuthEmulator } from "firebase/auth";
import { getStorage, connectStorageEmulator } from "firebase/storage";
import { getFirestore, connectFirestoreEmulator } from "firebase/firestore";
import { getFunctions, connectFunctionsEmulator } from "firebase/functions";

const firebaseConfig = {
"config"
  };
  
  // Initialize Firebase 
  const app = initializeApp(firebaseConfig);

  const auth = getAuth(app);
  const db = getFirestore(app);
  const storage = getStorage(app);
  const functions = getFunctions(getApp(), app);
  
  if (window.location.hostname.includes("localhost")) {
    connectAuthEmulator(auth, "http://localhost:9099");
    connectFirestoreEmulator(db, 'localhost', 8080);
    connectStorageEmulator(storage, 'localhost', 9199);
    connectFunctionsEmulator(functions, "localhost", 5001);
}

  export { auth, db, storage, functions };

Error Access to fetch at 'http://localhost:5001/app/object/addPost' 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. CORS 策略阻止了在“http://localhost:5001/app/object/addPost”从源“http://localhost:5173”获取的错误访问:对预检请求的响应未通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin”header。 If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.如果不透明的响应满足您的需求,请将请求的模式设置为“no-cors”以获取禁用 CORS 的资源。

What's the problem here?这里有什么问题? Will I need to set up firebase admin to grant access rights, and if I turn CORS off in the browser will that present a security issue on production?我是否需要设置 firebase 管理员来授予访问权限,如果我在浏览器中关闭 CORS 是否会在生产中出现安全问题?

As mentioned in the Answer , you can follow the checklist for the firebase callable functions cors errors:答案中所述,您可以按照 firebase 可调用函数 cors 错误的清单进行操作:

  1. Ensure the function is deployed.确保部署了 function。
  2. Ensure the function name is correct.确保 function 名称正确。 I was calling recalculatY when it should have been recalculateY .当它应该是recalculateY recalculatY Got a cors error for some reason.由于某种原因,出现 cors 错误。
  3. Ensure the function code itself is not throwing an error.确保 function 代码本身没有引发错误。 Use the emulator to help. 使用模拟器提供帮助。 This didn't throw a cors error, still helpful to know.这没有抛出 cors 错误,仍然有助于了解。
  4. Ensure your regions match - I am using europe-west2 .确保您的地区匹配 - 我正在使用europe-west2 I had to both deploy the function with that region, and call it using the region.我必须同时在该区域部署 function,并使用该区域调用它。 For a while, I assumed the client would infer the correct region if the function name was correct.有一段时间,我假设如果 function 名称正确,客户端会推断出正确的区域。

you can refer to the Documentation which explains about how to connect your app to cloud function emulator.您可以参考文档,其中解释了如何将您的应用程序连接到云 function 模拟器。

Before connecting your app to the Cloud Functions emulator, make sure that you nderstand the overall Firebase Local Emulator Suite workflow , and that you install and configure the Local Emulator Suite and review its CLI commands .在将您的应用程序连接到 Cloud Functions 模拟器之前,请确保您了解整个 Firebase Local Emulator Suite 工作流程,并安装和配置Local Emulator Suite 并查看其CLI 命令

you can refer to the Answer where below has been pointed out:您可以参考以下已指出的答案

For users who have the CORS preflight problem with the firebase local emulator , if you're using Webpack or Vue ( vue-cli ), you can resolve the situation with a proxy:对于使用firebase 本地仿真器vue-cli预检问题的用户,如果您使用的是WebpackVue ,则可以使用代理解决这种情况:

my-firebase-initialize-file.js (client side) my-firebase-initialize-file.js (客户端)

 firebase.functions().useFunctionsEmulator('http://localhost:1234/api'); // Client url + /api ``` **webpack.config.js** or **vue.config.js** *(client side, at the root, next to `package.json`)* ```lang-js module.exports = { devServer: { proxy: { "^/api": { target: "http://localhost:5001", // Emulator's url pathRewrite: { "^/api": "" }, ws: true, changeOrigin: true } } } }; ``` Now every `http://localhost:1234/api` will be proxied to `http://localhost:5001`, so you don't need CORS preflight anymore. Of course you need to adapt these **local** urls to your case.

For more information, you can refer to the Answer and git issue .更多信息可以参考Answer和git问题

After over a week of learning and trying to find the right solution for this problem, I came across a video from one of my favorite YT creators Web Dev Simplified.经过一个多星期的学习并试图找到解决这个问题的正确方法后,我看到了一个来自我最喜欢的 YT 创作者 Web Dev Simplified 的视频

Here he elegantly explains the CORS error and provides a simple yet effective solution.在这里,他优雅地解释了 CORS 错误,并提供了一个简单而有效的解决方案。 Installing the Express and CORS library through NPM within my cloud functions folder and requiring them both in the index.js file.通过 NPM 在我的云函数文件夹中安装 Express 和 CORS 库,并在 index.js 文件中要求它们。 Writing a function that allows you to change the access origin should be enough to solve this error.编写一个允许您更改访问来源的 function 应该足以解决此错误。

const express = require("express");
const app = express();
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();

const cors = require('cors');
app.use(
    cors({
        origin: "*",
    })
);

Changing the origin to "*" allows the access request origin to be from any source.将来源更改为“*”允许访问请求来源来自任何来源。 You can also change this to a specific URL if you needed.如果需要,您还可以将其更改为特定的 URL。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM