Firebase HostingデプロイメントでのGCPにホストされたVoiceVox APIとのCORS問題
Q&A
Closed
解決したいこと
Firebase HostingデプロイメントでのGCPにホストされたVoiceVox APIとのCORS問題を解決したいです。
発生している問題・エラー
Access to fetch at 'https://voicevox-proto-mggisi6odq-dt.a.run.app/audio_query?speaker=2&text=%20%E3%81%9D%E3%81%86%E3%81%A0%E3%81%AD%EF%BC%81' from origin 'https://aipartner-426616.web.app' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
該当するソースコード
// functions/src/index.ts
import * as functions from 'firebase-functions';
import express from 'express';
import cors from 'cors';
const app = express();
app.use(cors({ origin: true }));
app.get('/hello', (req, res) => {
res.send('Hello from Firebase!');
});
exports.api = functions.region('asia-east1').https.onRequest(app);
例)
// firebase.json
{
"functions": {
"source": ".firebase/aipartner-426616/functions",
"runtime": "nodejs14"
},
"hosting": {
"public": "out",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"function": "api"
}
]
}
}
// フロントエンドのリクエスト例
const VOICE_VOX_API_URL = process.env.NEXT_PUBLIC_VOICE_VOX_API_URL || 'http://localhost:50021';
export const fetchAudioVoiceVox = async (
talk: Talk,
speaker: string
): Promise<ArrayBuffer> => {
const ttsQueryResponse = await fetch(VOICE_VOX_API_URL + '/audio_query?speaker=' + speaker + '&text=' + encodeURIComponent(talk.message), {
method: 'POST',
});
if (!ttsQueryResponse.ok) {
throw new Error('Failed to fetch TTS query.');
}
const ttsQueryJson = await ttsQueryResponse.json();
ttsQueryJson['speedScale'] = 1.16;
ttsQueryJson['pitchScale'] = -0.02;
ttsQueryJson['intonationScale'] = 1.26;
const synthesisResponse = await fetch(VOICE_VOX_API_URL + '/synthesis?speaker=' + speaker, {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'Transfer-Encoding': 'chunked' },
body: JSON.stringify(ttsQueryJson)
});
if (!synthesisResponse.ok) {
throw new Error('Failed to fetch TTS synthesis result.');
}
const blob = await synthesisResponse.blob();
const buffer = await blob.arrayBuffer();
return buffer;
}
自分で試したこと
1.CORSミドルウェアを使用したFirebase Functionsの設定:
cors ミドルウェアを含むExpressアプリを持つFirebase Functionを作成しました。
2.Firebaseの設定:
functionsとhostingを設定するために firebase.json を更新しました。
3.FunctionレスポンスでのCORSヘッダー設定:
Firebase FunctionのレスポンスでCORSヘッダーを明示的に設定しました。
4.デプロイ:
firebase deploy --only functions,hosting を使用してfunctionsとhostingをデプロイしました。
上記の手順を踏んだにもかかわらず、デプロイされたフロントエンドからAPIにアクセスするとCORSエラーが発生し続けています。同じAPIリクエストはローカル開発時には問題なく動作します。
このCORS問題を解決するためのガイダンスや提案をいただけると幸いです。よろしくお願いします。