LoginSignup
16
12

More than 5 years have passed since last update.

Firebase Functions + TypeScript で CORS を使用する

Last updated at Posted at 2018-06-22

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

16
12
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
12