Table of Contents
POSTメソッドを叩いたらエラーが出た
NestJSで作成したAPIをLambdaに乗せ、API Gatewayでエンドポイントを作成した。
フロントエンドはNextJSで作成し、Vercelにデプロイした。
で、無事画面表示とGetが成功し、得たいデータが表示された。
ただPOST APIを叩いた時
Access to fetch at 'https://xxxxxx.amazonaws.com/api/v1/login' from origin 'https://xxxxxxx.vercel.app' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.というエラーがでた。
CORSは有効にしている
上のエラーを読む限り、CORSに関するエラーということがわかる。
ただNestJSの方でCORSは有効にしている。
該当のソースは下記の通り。
const app = await NestFactory.create(AppModule); await app.init();
app.useGlobalPipes(new ValidationPipe()); app.useGlobalFilters(new HttpExceptionFilter());
// CORSの有効化 app.enableCors();
const expressApp = app.getHttpAdapter().getInstance(); return serverlessExpress({ app: expressApp });Getはできているし、CORSもきっと有効に出来ているに違いない。
じゃあ、なんでPOSTはできないの?
沼に落ちた。
解決方法
ちなみに同じ状況に陥った人のために先に解決方法を載せておくと、下記のようにawait app.init();の位置が肝だった。
const app = await NestFactory.create(AppModule);app.enableCors()app.useGlobalPipes(new ValidationPipe());app.useGlobalFilters(new HttpExceptionFilter());await app.init();const expressApp = app.getHttpAdapter().getInstance();return serverlessExpress({ app: expressApp });理由はいまいちわからないので、ここには記載しない。
ここに至るまでの道のり(読むかは自己判断で)
上記の通りで解決するので後はただの蛇足。
ただ自分がどのように解決に至ったかをログとして残しておく。
見る価値があるかはわからない。
API GatewayでCORSを設定する
AWSのほうでも同様にCORSを設定する必要があるのか? という思いで設定した。
API Gateway > CORSで設定にいき、下記の通り設定した。
| Access-Control-Allow-Origin | * |
|---|---|
| Access-Control-Allow-Headers | content-type,authorization |
| Access-Control-Allow-Methods | GET,POST,PUT,DELETE,OPTIONS |
がエラーが変わらないので、ReactからCognitoで認証認可されたAPI Gatewayを呼び出すを参考に下記の通り変更した。
| Access-Control-Allow-Origin | https://vote-for-name.vercel.app |
|---|---|
| Access-Control-Allow-Headers | content-type,authorization |
| Access-Control-Allow-Methods | * |
| Access-Control-Max-Age | -1秒 |
| Access-Control-Allow-Credentials | true |
に変更したが意味がなかった。
※ てかNestJSでCORSを設定しなくてもここで設定できる?(未確認)それならソースビルドしなくていいので負担が減りそう。いつか試してみたい。
## NestJS側でCORS有効化の書き方を変更してみる
const app = await NestFactory.create(AppModule); await app.init();
app.useGlobalPipes(new ValidationPipe()); app.useGlobalFilters(new HttpExceptionFilter());
app.use((req: any, res: any, next: any) => { res.header('Access-Control-Allow-Origin', '*'); res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization'); res.header('Access-Control-Allow-Methods', '*'); next(); });
const expressApp = app.getHttpAdapter().getInstance(); return serverlessExpress({ app: expressApp });にしたみたけど変わらず、エラーが出続ける。
そもそも
app.use((req: any, res: any, next: any) => { res.header('Access-Control-Allow-Origin', '*'); res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization'); res.header('Access-Control-Allow-Methods', '*'); next(); });これを追加した時点で、
app.enableCors()を削除してるけど、これも必要なんじゃないかということで復活してみる。
が、変わらず無理のまま。
エラーでpreflightがどうこう言っているので、
if ('OPTIONS' == req.method) { res.send(204);}else { next();}CORS “It does not have HTTP ok status.”上記を追加してみた。
ができない。
同様に、上記サイトを参考にapp.options('*', cors())を追加し見たが、そんな型存在しないともっと前の段階で怒られた。
Githubで他の人のソースを探る
どうやら順番が違うことに気が付いて無事解決。
諦めずに取り組んで良かった。