Federico Elles
Federico Elles

Reputation: 4679

Google Cloud Functions enable CORS?

I just finished the Hello World Google Cloud Functions tutorial and received the following response headers:

Connection → keep-alive
Content-Length → 14
Content-Type → text/plain; charset=utf-8
Date → Mon, 29 Feb 2016 07:02:37 GMT
Execution-Id → XbT-WC9lXKL-0
Server → nginx

How can I add the CORS headers to be able to call my function from my website?

Upvotes: 57

Views: 56592

Answers (10)

ggorlen
ggorlen

Reputation: 57259

If you tried the accepted answer but encountered a preflight error, the docs offer examples of handling it in multiple languages, with the caveat that it only works on public functions, i.e. deployed with --allow-unauthenticated:

exports.corsEnabledFunction = (req, res) => {
  res.set("Access-Control-Allow-Origin", "*");

  if (req.method === "OPTIONS") {
    /* handle preflight OPTIONS request */
    
    res.set("Access-Control-Allow-Methods", "GET, POST");
    res.set("Access-Control-Allow-Headers", "Content-Type");

    // cache preflight response for 3600 sec
    res.set("Access-Control-Max-Age", "3600");
    
    return res.sendStatus(204);
  }

  // handle the main request
  res.send("main response");
};

Another option is to use Express as shown in this post, complete with cross-origin enabled.

Upvotes: 4

Jason Polites
Jason Polites

Reputation: 5800

I'm the product manager for Google Cloud Functions. Thanks for your question, this has been a popular request.

We don't have anything to announce just yet, but we're aware of several enhancements that need to be made to the HTTP invocation capabilities of Cloud Functions and we'll be rolling out improvements to this and many other areas in future iterations.

UPDATE:

We've improved the way you deal with HTTP in Cloud Functions. You now have full access to the HTTP Request/Response objects so you can set the appropriate CORS headers and respond to pre-flight OPTIONS requests (https://cloud.google.com/functions/docs/writing/http)

UPDATE (2022):

Just noticed there was a question about docs, and our docs have moved. Updated docs for CORS are here:

https://cloud.google.com/functions/docs/samples/functions-http-cors

Upvotes: 34

Axel
Axel

Reputation: 1

After CORS enabled if you send POST request to your function also check for your request Content-Type header, mine was set it to "text/plain" and my browser was constantly triggering CORS errors, after setting the header to "application/json" everything worked properly.

Upvotes: 0

GuilleOjeda
GuilleOjeda

Reputation: 3361

After applying your favourite answer from here, if you're still getting this error, check for uncaught errors in your cloud function. This can result in the browser receiving a CORS error, even when your error has nothing to do with CORS

Upvotes: 1

spencercooly
spencercooly

Reputation: 6636

here we go:

exports.helloWorld = function helloWorld(req, res) {  
  res.set('Access-Control-Allow-Origin', "*")
  res.set('Access-Control-Allow-Methods', 'GET, POST');

  if (req.method === "OPTIONS") {
    // stop preflight requests here
    res.status(204).send('');
    return;
  }

  // handle full requests
  res.status(200).send('weeee!);
};

then you can jquery/whatever it as usual:

$.get(myUrl, (r) => console.log(r))

Upvotes: 94

Antier Solutions
Antier Solutions

Reputation: 1402

You need to send an 'OPTIONS' response by setting its header as follows:

if (req.method === 'OPTIONS') {
  res.set('Access-Control-Allow-Methods', '*');
  res.set('Access-Control-Allow-Headers', '*');
  res.status(204).send('');
}

Runtime: NodeJS 10

Upvotes: 4

Oleksandr Marchuk
Oleksandr Marchuk

Reputation: 21

You must enable CORS within all your functions, for example hello function:

index.js

const cors = require('cors')();

// My Hello Function
function hello(req, res) {
  res.status(200)
    .send('Hello, Functions');
};

// CORS and Cloud Functions export
exports.hello = (req, res) => {
  cors(req, res, () => {
    hello(req, res);
  });
}

Don't forget about package.json

package.json

{
  "name": "function-hello",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "cors": "^2.8.5"
  }
}

Upvotes: 2

half-hitch
half-hitch

Reputation: 173

In the python environment, you can use the flask request object to manage CORS requests.

def cors_enabled_function(request):
    if request.method == 'OPTIONS':
        # Allows GET requests from any origin with the Content-Type
        # header and caches preflight response for an 3600s
        headers = {
            'Access-Control-Allow-Origin': '*',
            'Access-Control-Allow-Methods': 'GET',
            'Access-Control-Allow-Headers': 'Content-Type',
            'Access-Control-Max-Age': '3600'
        }

        return ('', 204, headers)

    # Set CORS headers for the main request
    headers = {
        'Access-Control-Allow-Origin': '*'
    }

    return ('Hello World!', 200, headers)

See the gcloud docs for more.

Upvotes: 4

Nicolas Dao
Nicolas Dao

Reputation: 1107

I've just created webfunc. It's a lightweight HTTP server that supports CORS as well as routing for Google Cloud Functions. Example:

const { serveHttp, app } = require('webfunc')

exports.yourapp = serveHttp([
  app.get('/', (req, res) => res.status(200).send('Hello World')),
  app.get('/users/{userId}', (req, res, params) => res.status(200).send(`Hello user ${params.userId}`)),
  app.get('/users/{userId}/document/{docName}', (req, res, params) => res.status(200).send(`Hello user ${params.userId}. I like your document ${params.docName}`)),
])

In your project's root, simply add a appconfig.json that looks like this:

{
  "headers": {
    "Access-Control-Allow-Methods": "GET, HEAD, OPTIONS, POST",
    "Access-Control-Allow-Headers": "Origin, X-Requested-With, Content-Type, Accept",
    "Access-Control-Allow-Origin": "*",
    "Access-Control-Max-Age": "1296000"
  }
}

Hope this helps.

Upvotes: 5

Gary
Gary

Reputation: 831

You can use the CORS express middleware.

package.json

npm install express --save
npm install cors --save

index.js

'use strict';

const functions = require('firebase-functions');
const express = require('express');
const cors = require('cors')({origin: true});
const app = express();

app.use(cors);
app.get('*', (req, res) => {
    res.send(`Hello, world`);
});

exports.hello = functions.https.onRequest(app);

Upvotes: 7

Related Questions