私は現在Firebase用の新しいCloud Functionsの使い方を学んでいますが、私が抱えている問題はAJAXリクエストを通して書いた関数にアクセスできないということです。 「アクセス制御許可の発生元がありません」というエラーが表示されます。これが私が書いた関数の例です:
exports.test = functions.https.onRequest((request, response) => {
response.status(500).send({test: 'Testing functions'});
})
関数はこのURLにあります。 https://us-central1-fba-shipper-140ae.cloudfunctions.net/test
Firebaseのドキュメントでは、CORSミドルウェアを関数内に追加することを提案しています。試してみましたが、動作しません。 https://firebase.google.com/docs/functions/http-events
これが私のやり方です。
var cors = require('cors');
exports.test = functions.https.onRequest((request, response) => {
cors(request, response, () => {
response.status(500).send({test: 'Testing functions'});
})
})
何がおかしいのですか?私はこれでどんな助けにでも感謝するでしょう。
更新:
Doug Stevenson の回答が助けになりました。 ({Origin:true})を追加して問題を解決しました。response.status(500)
をresponse.status(200)
に変更する必要もありましたが、最初は完全に見逃していました。
Firebaseチームが提供するCORSの使用方法を示す2つの サンプル関数 があります。
2番目のサンプルは、現在使用している方法とは異なる方法でcorsを使用します。
また、サンプルに示すように、このようにインポートすることを検討してください。
const cors = require('cors')({Origin: true});
このようにクラウド関数でCORSを設定できます。response.set('Access-Control-Allow-Origin', '*');
cors
パッケージをインポートする必要はありません。
TypeScriptでこれをやろうとしている人のためにこれはコードです:
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
});
しばらくしてからこれをグーグルする人のために、もう1つ情報を追加します。firebase hostingを使用している場合は、たとえば(firebase_hosting_Host)/ api/myfunctionのようなURLを( firebase_cloudfunctions_Host)/ doStuff関数このように、リダイレクトは透過的でサーバーサイドなので、あなたはコアを扱う必要はありません。
Firebase.jsonの書き換えセクションでそれを設定できます。
"rewrites": [
{ "source": "/api/myFunction", "function": "doStuff" }
]
私は@Andreysが彼自身の質問に答えることに少し追加しています。
cors(req, res, cb)
関数でコールバックを呼び出す必要がないように思われるので、すべてのコードをコールバックに埋め込むことなく、関数の先頭にあるcorsモジュールを呼び出すだけで済みます。後でcorsを実装したい場合は、これははるかに速くなります。
exports.exampleFunction = functions.https.onRequest((request, response) => {
cors(request, response, () => {});
return response.send("Hello from Firebase!");
});
冒頭の記事で述べたように、CORを初期化することを忘れないでください。
const cors = require('cors')({Origin: true});
CORSソリューションは私のために働きませんでした...今まで!
他の誰かが私がやったのと同じ問題に遭遇したかどうかわからないが、私は私が見つけた例から5つの異なる方法のようにCORSをセットアップし、何もうまくいかないようだった。私はそれが本当にバグであるかどうかを確かめるためにPlunkerで最小限の例を設定しました、しかし例は美しく走りました。私はそれが私に何かを伝えることができるかどうか見るためにfirebase機能ログ(firebaseコンソールにある)をチェックすることにしました。 私は自分のノードサーバーコードに2、3のエラーがありました、CORS関連ではありません、デバッグしたときCORSエラーメッセージを私にリリースしました。 CORSとは無関係のコードエラーがCORSエラー応答を返す理由はわかりませんが、それが間違ったウサギの穴を何時間もの間私を導いてくれました...
tl; dr - CORSソリューションが機能しない場合はfirebaseの機能ログを確認し、エラーがあればデバッグします。
私はそのことについて少しだけ出版したところです。
https://mhaligowski.github.io/blog/2017/03/10/cors-in-cloud-functions.html
一般的には、Express CORS package を使うべきです。これはGCF/Firebase Functionsの要件を満たすために少し手を加える必要があります。
それが役立つことを願っています!
これは役に立つかもしれません。 express(カスタムURL)でfirebase HTTPクラウド機能を作成しました
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);
書き換えセクションを追加したことを確認してください
"rewrites": [
{
"source": "/api/v1/**",
"function": "functionName"
}
]
私は私の要求で承認を持っているので、この方法だけが私のために働く:
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)
} )};
app
をonRequest
に渡すときに同じ問題を抱えていたのは価値があることです。私は、この問題がfirebase機能のリクエストURLの末尾のスラッシュであることに気付きました。 Expressは'/'
を探していましたが、関数[project-id].cloudfunctions.net/[function-name]
の末尾にスラッシュがありませんでした。 CORSエラーは偽陰性でした。末尾のスラッシュを追加すると、期待したとおりの応答が得られました。
私のような人がいる場合:クラウド関数と同じプロジェクトからクラウド関数を呼び出す場合、firebase sdkを初期化してonCallメソッドを使用できます。それはあなたのためにすべてを処理します:
exports.newRequest = functions.https.onCall((data, context) => {
console.log(`This is the received data: ${data}.`);
return data;
})
この関数を次のように呼び出します。
// Init the firebase SDK first
const functions = firebase.functions();
const addMessage = functions.httpsCallable(`newRequest`);
Firebase docs: https://firebase.google.com/docs/functions/callable
SDKを初期化できない場合は、他の提案の本質がここにあります。
Expressを使用していない場合、または単にCORSを使用したい場合次のコードは解決に役立ちます
const cors = require('cors')({ Origin: true, });
exports.yourfunction = functions.https.onRequest((request, response) => {
return cors(request, response, () => {
// *Your code*
});
});