クソ丸一日くらいこれに費やした。他の人には30分で抜け出してほしいので共有。
一応基本的なところは理解して、CORSリクエストヘッダによる応答で問題解決の方法まで把握していたつもりだった。今回頭を悩ませた最大の要因は、すでに機能している POST/GET 系の REST API と全く同じ呼び方をしているのに PUT/DELETE を行おうとすると CORS 問題に蹴られて REST の呼び出しすらかからないということ。
もっと早く「メソッドの違いによる」ってわかってたら検索ワードも違ってたのかもしれないな。プリフライトのエラーも、前回 POST で悩んでたときにも見かけた気がしていたのであまり気に留めてなかった。
今回の問題をかいつまむと、
- POST/GET/HEAD リクエストは Simple Request と呼ばれ、リクエストを受けた応答ヘッダでCORS Accept xxx を送信してあげればよかった。
- PUT/DELETE のリクエストは非 Simple Request ということで、そもそもリクエストを受け取るかどうか判断するためにプリフライト判定という手続きが必要。
本当にいろいろな人がまとめてくれてる。こことか、こことか。個人的に一番シンプルでわかりやすかったのはここ。
解決策
手元の実装は express モジュールと router 使っていたのだけれど、後述にある通り「router.delete(‘/somerestapi’,…」じゃなくて、その外側でなんとかしてあげなきゃいけないんじゃね?と気づきを与えてくれたのはこの記事だった。結局下の魔法の4行で問題解決したよ。
const express = require('express');
const cors = require('cors');
var app = express();
app.use(cors());
問題とは関係なかったこと (時間の無駄遣い)
いろんな所に意識が散って時間を掛ける原因となってしまったいくつかの要素、結局関係なかったから、他の人もしここにあまり時間使いすぎてるようならば別の可能性も探ったほうがいいぜということで書いとくね。
- DELETE メソッドに body 要素は不要 (Content-Length: 0)
- これが原因でCORS問題とかないから。まあ落ち着け。
- Access-Control-Allow のメソッドとかヘッダーとか
- そもそもこいつらを設定している REST API のデバッグ出力が確認できなかった = 呼び出されてない、だからね。解決策は呼びされる外側にあることに気づこう。