1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Cloud Runで発生するCORSエラーの原因と解消方法

Posted at

概要

Cloud Run上でバックエンドAPIを運用していると、フロントエンド(Vercelやローカル開発環境)からのリクエスト時にCORSエラーが発生することがあります。この記事ではCORSエラーをCloud Run環境下で解消した方法を解説します。

CORSとは

簡単にいうとブラウザが仲介者としてクライアントとサーバーの間で安全確認をする仕組み のことです。

CORSエラーとは何か

たとえば自分のWebアプリがhttp://localhost:3000で動いていて、
そこから別のサイトにデータを取りに行くとします。

このとき「そのAPIは本当に安全かわからないので、勝手にアクセスしてはダメかもしれない」と安全性の観点でブラウザに止められることがCORSエラーです。

CORSエラーの具体例

ブラウザがフロントからサーバーにリクエストを送信しようとしたとき、
次のようなエラーが出ました。

  • フロント:https://xxxx.vercel.app
  • サーバー:https://xxxx-server-xxxxxx.run.app
Access to fetch at 'https://rootlink-server.run.app/chat' from origin 'https://rootlink.vercel.app' has been blocked by CORS policy.

原因

ブラウザはセキュリティのため、本リクエストを送る前に下見をします。これが「プリフライトリクエスト(OPTIONS)」です。

  1. ブラウザがまず OPTIONS をサーバーに送信
  2. サーバーがこのサイト安全性をチェックする
  3. その後に本リクエスト(POSTなど)を送信

しかしサーバーが正しく返さないと、ブラウザは通信を止めます。

この場合、ブラウザはリクエストを送る前に プリフライトリクエストを自動で送信します。サーバーがこのプリフライトに正しく応答しないと、ブラウザが本リクエストをブロックしこのようなエラーが発生してしまいます。

解決策:Hono + Cloud Run の場合

Cloud RunでHonoを使っている場合、以下のようにCORSをグローバルに設定することで解消できます。

// --- 必要なモジュールを読み込み ---
// Hono: 軽量なWebサーバーフレームワーク(Expressの代わり)
import { Hono } from 'hono';
// CORS(他のサイトからのアクセス制限)を設定するためのミドルウェア
import { cors } from 'hono/cors';
// Node.jsでHonoアプリを動かすための関数
import { serve } from '@hono/node-server';

// --- アプリ本体を作成 ---
const app = new Hono();

// --- CORS設定 ---
// どのサイト(オリジン)からアクセスを許可するかを定義
app.use(
  '/*', // すべてのルートに適用
  cors({
    // アクセス元(Origin)をチェック
    origin: (origin) => {
      // originが無い場合(例:サーバー内部の通信など)は全部許可
      if (!origin) return '*';

      // vercel.appドメイン(開発・本番)を許可
      if (origin.endsWith('.vercel.app')) return origin;

      // ローカル開発環境(Viteなど)を許可
      if (origin === 'http://localhost:5173') return origin;

      // 明示的に本番ドメインを許可
      if (origin === 'https://rootlink.vercel.app') return origin;

      // それ以外は一時的に全許可(※本番ではできるだけ制限する)
      return '*';
    },
    // 許可するHTTPメソッド(GET, POSTなど)
    allowMethods: ['GET', 'POST', 'OPTIONS'],
    // 許可するヘッダー(Content-Typeなど)
    allowHeaders: ['Content-Type', 'Authorization'],
  })
);

// --- プリフライトリクエスト(OPTIONS)の明示的な処理 ---
// ブラウザが安全確認のために送るOPTIONSリクエストに対して、
// OKと返す ステータスコード204=成功
app.options('*', (c) => c.text('ok', 204));

// --- 通常のGETリクエスト(動作確認用) ---
// 例: https://rootlink-server-xxxxxx.run.app/ にアクセスしたら "OK" を返す
app.get('/', (c) => c.text('OK'));

// --- サーバーを起動 ---
// PORT環境変数があれば使い、なければ8080番で起動
const port = Number(process.env.PORT) || 8080;

// Honoアプリをサーバーとして起動
serve({ fetch: app.fetch, port });

まとめ

  • CORSエラーはブラウザのセキュリティ機構によるもの
  • サーバー側でAccess-Control-Allow-Origin等のヘッダーを正しく返す必要がある
  • Cloud Run上でHonoを使用する場合、hono/corsを適用し、OPTIONSメソッドを処理すれば解消可能

1
0
0

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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?