Help us understand the problem. What is going on with this article?

Firebase Functions + TypeScript で CORS を使用する

More than 1 year has passed since last update.

Web API のプロトタイプを Firebase Functions の http ハンドラーを使って実装して、それを JavaScript から呼び出したら、 No 'Access-Control-Allow-Origin' header のエラーが出たので、それに対応した手順を書きます。

まず

Firebase Functions を REST API のように 即時に応答を要求する用途 に使うのはほとんどの場合間違っています。一般的に、クラウドプラットフォームで提供される "Functions" と呼ばれる機能は、起動は遅いと考えたほうがよいです。

Functions

次のような say 関数を作りました、TypeScript で。

import * as functions from 'firebase-functions';
export const say = functions.https.onRequest((request, response) => {
    response.send("Hello from Firebase!");
});

サンプルまんまです。

firebase serve をして、ローカルで動作させると、
http://localhost:5001/<project名>/us-central1/say のような URL で起動できます。

HTML

これを呼び出す HTML を次のように書きました。
この index.html は Firebase Hosting に配置するので、 public ディレクトリに置きます。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Firebase Hosting</title>
    <script type="text/javascript">
    function loadHello() {
      var label = document.getElementById("label");

      var req = new XMLHttpRequest();
      req.onreadystatechange = function() {
        if (req.readyState == 4) { 
          if (req.status == 200) {
            label.innerHTML = req.responseText;
          }
        } else {
          label.innerHTML = "通信中...";
        }
      }

      req.open('GET', 'http://localhost:5001/<プロジェクト名>/us-central1/say', true);
      req.send(null);
    }
    </script>
  </head>
  <body onLoad="loadHello()">
    <H1>Firebase Hosting</H1>
    <div id="label">loading..</div>
  </body>
</html>

こちらも firebase serve しているときに http://localhost:5000/ でアクセスできます。

*No Access-Control-Allow-Origin エラー

index.html は、読み込み時に Functions の /say を呼び出して、そのレスポンスを id=label に表示する、というものですが、読み込み時に Console にエラーが出ます。

Failed to load http://localhost:5001/xxxx/us-central1/say: 
No 'Access-Control-Allow-Origin' header is present on the requested resource. 
Origin 'http://localhost:5000' is therefore not allowed access.

よくあるやつです。

Functions で CORS を使う

Functions を CORS に対応させる(別ドメインからの呼び出しを許可する)には、expressjs/cors: Node.js CORS middleware という node.js 用ライブラリを使います。今回は TypeScript なので、これの type definitions である

を使います。

まずは cors と @types/cors をインストールします。

npm install --save cors
npm install --save-dev @types/cors

functions/package.json は次のようになっています。

{
  "name": "functions",
  "scripts": {
    "lint": "tslint --project tsconfig.json",
    "build": "tsc",
    "serve": "npm run build && firebase serve --only functions",
    "shell": "npm run build && firebase functions:shell",
    "start": "npm run shell",
    "deploy": "firebase deploy --only functions",
    "logs": "firebase functions:log"
  },
  "main": "lib/index.js",
  "dependencies": {
    "cors": "^2.8.4",
    "firebase-admin": "~5.12.1",
    "firebase-functions": "^1.0.3"
  },
  "devDependencies": {
    "@types/cors": "^2.8.4",
    "tslint": "^5.8.0",
    "typescript": "^2.5.3"
  },
  "private": true
}

続いて Functions を次のように書き換えます。

import * as functions from 'firebase-functions';
import * as corsLib from 'cors';
const cors = corsLib();

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

cors を import して関数として実行。
さらに onRequest の中を、 cors(req, res, ()=>{ }) で包んじゃいます。

これで html を表示させると、エラーは消え、次のような画面が表示できます。

image.png

amay077
ランチの時は呼ぶといい!
https://blog.amay0777.net/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした