web-dev-qa-db-de.com

Aktivieren von CORS in Cloud-Funktionen für Firebase

Ich lerne gerade, wie man neue Cloud-Funktionen für Firebase verwendet. Das Problem, das ich habe, ist, dass ich nicht auf die Funktion zugreifen kann, die ich über eine AJAX -Anfrage geschrieben habe. Ich erhalte die Fehlermeldung "Kein Zugriffskontroll-Zulassen-Ursprung". Hier ist ein Beispiel für die Funktion, die ich geschrieben habe:

exports.test = functions.https.onRequest((request, response) => {
  response.status(500).send({test: 'Testing functions'});
})

Die Funktion befindet sich in dieser URL: https://us-central1-fba-shipper-140ae.cloudfunctions.net/test

Firebase docs schlägt vor, CORS-Middleware in die Funktion einzufügen. Ich habe es versucht, aber es funktioniert nicht für mich: https://firebase.google.com/docs/functions/http-events

So habe ich es gemacht:

var cors = require('cors');    

exports.test = functions.https.onRequest((request, response) => {
   cors(request, response, () => {
     response.status(500).send({test: 'Testing functions'});
   })
})

Was mache ich falsch? Ich würde mich über jede Hilfe freuen.

AKTUALISIEREN:

Die Antwort von Doug Stevenson half. Durch das Hinzufügen von ({Origin: true}) wurde das Problem behoben. Ich musste auch response.status(500) in response.status(200) ändern, was ich zunächst völlig vermisst hatte.

62

Es gibt zwei Beispielfunktionen , die vom Firebase-Team bereitgestellt werden, um die Verwendung von CORS zu demonstrieren:

Das zweite Beispiel verwendet eine andere Art der Arbeit mit Cors als Sie derzeit verwenden.

Erwägen Sie auch das Importieren wie in den Beispielen gezeigt:

const cors = require('cors')({Origin: true});
82
Doug Stevenson

Sie können das CORS in der Cloud-Funktion folgendermaßen einstellen: response.set('Access-Control-Allow-Origin', '*'); Das Paket cors muss nicht importiert werden

18

Für jeden, der versucht, dies in TypeScript zu tun, ist dies der Code:

import * as cors from 'cors';
const corsHandler = cors({Origin: true});

export const exampleFunction= functions.https.onRequest(async (request, response) => {
       corsHandler(request, response, () => {});
       //Your code here
});
17
Yayo Arellano

Ich habe eine kleine Ergänzung zu @Andreys Antwort auf seine eigene Frage.

Es sieht so aus, als müssten Sie den Rückruf nicht in der Funktion cors(req, res, cb) aufrufen. Sie können also das cors-Modul ganz oben in Ihrer Funktion aufrufen, ohne den gesamten Code in den Rückruf einzubetten. Dies geht viel schneller, wenn Sie cors nachträglich implementieren möchten.

exports.exampleFunction = functions.https.onRequest((request, response) => {
    cors(request, response, () => {});
    return response.send("Hello from Firebase!");
});

Vergessen Sie nicht, die im Eröffnungsbeitrag genannten Kore zu initiieren:

const cors = require('cors')({Origin: true});

15
Jaap Weijland

Eine weitere Info, nur für diejenigen, die nach einiger Zeit googeln: Wenn Sie Firebase-Hosting verwenden, können Sie auch Umschreibungen einrichten, sodass beispielsweise eine URL (firebase_hosting_Host)/api/myfunction umgeleitet wird an die Funktion (firebase_cloudfunctions_Host)/doStuff. Da die Umleitung transparent und serverseitig ist, müssen Sie nicht mit cors umgehen.

Sie können dies mit einer Umschreibungssektion in firebase.json einrichten:

"rewrites": [
        { "source": "/api/myFunction", "function": "doStuff" }
]
13
Pablo Urquiza

Ich habe gerade ein kleines Stück dazu veröffentlicht:

https://mhaligowski.github.io/blog/2017/03/10/cors-in-cloud-functions.html

Im Allgemeinen sollten Sie das Paket Express CORS verwenden, das ein wenig herumhackt, um die Anforderungen in den GCF/Firebase-Funktionen zu erfüllen.

Hoffentlich hilft das!

6
mhaligowski

Keine CORS-Lösungen funktionierten für mich ... bis jetzt!

Ich bin mir nicht sicher, ob jemand anderes auf dasselbe Problem gestoßen ist wie ich, aber ich habe CORS auf 5 verschiedene Arten von Beispielen eingerichtet, die ich gefunden habe und nichts schien zu funktionieren. Ich habe ein minimales Beispiel mit Plunker eingerichtet, um zu sehen, ob es wirklich ein Fehler war, aber das Beispiel lief wunderbar. Ich beschloss, die Protokolle der Firebase-Funktionen (die in der Firebase-Konsole zu finden sind) zu überprüfen, um zu sehen, ob mir das etwas sagen könnte. Ich hatte ein paar Fehler in meinem Knotenservercode , nicht im Zusammenhang mit CORS , die beim Debuggen von mich von meiner CORS-Fehlernachricht befreit haben . Ich weiß nicht, warum Codefehler, die nicht mit CORS in Verbindung stehen, eine CORS-Fehlerantwort zurückgeben, aber es hat mich für eine gute Anzahl von Stunden in das falsche Kaninchenloch geführt ...

tl; dr - Überprüfen Sie Ihre Firebase-Funktionsprotokolle, ob keine CORS-Lösungen funktionieren, und debuggen Sie eventuelle Fehler

4
tbone849

Das könnte hilfreich sein. Ich habe eine Firebase-HTTP-Cloud-Funktion mit Express (benutzerdefinierte URL) erstellt.

const express = require('express');
const bodyParser = require('body-parser');
const cors = require("cors");
const app = express();
const main = express();

app.post('/endpoint', (req, res) => {
    // code here
})

app.use(cors({ Origin: true }));
main.use(cors({ Origin: true }));
main.use('/api/v1', app);
main.use(bodyParser.json());
main.use(bodyParser.urlencoded({ extended: false }));

module.exports.functionName = functions.https.onRequest(main);

Stellen Sie sicher, dass Sie Abschnitte zum Umschreiben hinzugefügt haben

"rewrites": [
      {
        "source": "/api/v1/**",
        "function": "functionName"
      }
]
2
Sandy

Nur dieser Weg funktioniert für mich, da ich die Berechtigung für meine Anfrage habe:

exports.hello = functions.https.onRequest((request, response) => {
response.set('Access-Control-Allow-Origin', '*');
response.set('Access-Control-Allow-Credentials', 'true'); // vital
if (request.method === 'OPTIONS') {
    // Send response to OPTIONS requests
    response.set('Access-Control-Allow-Methods', 'GET');
    response.set('Access-Control-Allow-Headers', 'Content-Type');
    response.set('Access-Control-Max-Age', '3600');
    response.status(204).send('');
} else {
    const params = request.body;
    const html = 'some html';
    response.send(html)
} )};
2
Gleb Dolzikov

Für das, was es wert ist, hatte ich dasselbe Problem, als app in onRequest übergeben wurde. Mir wurde klar, dass das Problem ein nachstehender Schrägstrich bei der Anforderungs-URL für die Firebase-Funktion war. Express suchte nach '/', aber ich hatte keinen abschließenden Schrägstrich für die Funktion [project-id].cloudfunctions.net/[function-name]. Der CORS-Fehler war falsch negativ. Als ich den nachstehenden Schrägstrich hinzufügte, erhielt ich die erwartete Antwort. 

1
shadyhill

Wenn es Leute wie mich gibt: Wenn Sie die Cloud-Funktion aus demselben Projekt wie die Cloud-Funktion selbst aufrufen möchten, können Sie das Firebase-SDK starten und die onCall-Methode verwenden. Es wird alles für Sie erledigen:

exports.newRequest = functions.https.onCall((data, context) => {
    console.log(`This is the received data: ${data}.`);
    return data;
})

Rufen Sie diese Funktion folgendermaßen auf:

// Init the firebase SDK first    
const functions = firebase.functions();
const addMessage = functions.httpsCallable(`newRequest`);

Firebase-Dokumente: https://firebase.google.com/docs/functions/callable

Wenn Sie das SDK nicht einleiten können, ist dies die Essenz aus den anderen Vorschlägen:

0
Chronnie

Wenn Sie nicht Express verwenden oder einfach CORS verwenden möchten. Der folgende Code hilft bei der Lösung

const cors = require('cors')({ Origin: true, });   
exports.yourfunction = functions.https.onRequest((request, response) => {  
   return cors(request, response, () => {  
        // *Your code*
    });
});
0
krishnazden