おひとり

できる限りひとりで楽しむための情報やプログラミング情報など。

Fetch APIでHTTP PATCHリクエストだけが失敗するバグの解決策

TL;DR

methodの指定をpatchからPATCHと、大文字に変更してください。

 method: "patch", // NG!!
----
 method: "PATCH", // OK

fetch()で「patch」リクエストが通らない

以下のようなコードを使ってHTTP PATCHを送ろうとしてもうまくいきません。

const response = await fetch(`some/api/endpoint`, {
    method: "patch",  // <---------------------- 小文字になっていませんか?
});

自分の環境(Chrome)では、net::ERR_EMPTY_RESPONSEというエラーになりました。

fetch()を使う場合、HTTPリクエストメソッドはpatchではなく、全て大文字のPATCHで指定する必要があります。
小文字にしている場合は大文字に直すことで(それ以外にエラーがなければ)動作するようになります。

postとかは小文字でもいけるよ??

まず、HTTPのメソッド名は大文字と小文字を区別する(case-sensitive)仕様になっています。
HTTPのメソッドはオブジェクトシステムのゲートウェイとして(つまりオブジェクト指向言語のメソッド名として)使われることを想定しているから、という事のようです。(プログラミング言語での「オブジェクトのメソッド」は基本的にcase-sensitiveです。)

すなわち、getではなく、GETと指定する必要があります。

しかし、Fetch APIの仕様によると、 以下のメソッドについては正規化(Normalization)のため、fetch()内部で大文字に変換されるとのこと。

  • DELETE
  • GET
  • HEAD
  • OPTIONS
  • POST
  • PUT

To normalize a method, if it is a byte-case-insensitive match for DELETE, GET, HEAD, OPTIONS, POST, or PUT, byte-uppercase it.

https://fetch.spec.whatwg.org/#methods

そのため、GETPOSTgetpostとそれぞれ小文字で指定しても「fetch()がよしなに大文字に変換してくれていた」から問題なく通信できた、ということですね。

しかし、PATCHはこの「正規化(Normalization)」するメソッド一覧に含まれていません。
よって、fetch()内部で自動で大文字に変換されず、HTTPの仕様(case-sensitive)に反していたため通信できなかったという訳ですね。

まとめ

fetch()PATCHのリクエストを送信するときは、メソッド名は必ず大文字のPATCHで指定しよう。

参考リンク

Fetch Standard

http method patch is case sensitive · Issue #254 · github/fetch · GitHub

Add PATCH HTTP verb normalization · Issue #37 · github/fetch · GitHub

RFC 7230 - Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing

RFC 7231 - Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content

f:id:hitoridehitode:20200629171947p:plain:w100