URL の末尾のスラッシュの有無はそれぞれアクセス対象がディレクトリかファイルかを示します。このため API にアクセスする時の URL において末尾のスラッシュはない状態が望ましいです。末尾スラッシュが入っている場合、web サーバ(Apache, nginxなど)はHTTPステータス 301 のリダイレクトレスポンスを返すことが多いです。このリダイレクト時にはもともとのリクエストが POST メソッドであっても強制的に GET メソッドとなり、リダイレクト元とは全く違う API を叩くことになりバグとなりえます。この記事では JavaScript の HTTP クライアントライブラリである axios を用いた時の末尾スラッシュ対策を紹介します。
axios は JavaScript の HTTP クライアントライブラリです。少なくない JavaScript プログラムの HTTP 通信がこのライブラリを介して行われています。この axios で末尾スラッシュの除去
axios/axios: Promise based HTTP client for the browser and node.js
axios には interceptors という仕組みがあり、これを使うことでリクエスト時にリクエスト内容を加工できます。次のようにすることで axios が呼び出される際の URL の末尾にスラッシュが含まれていても、通信相手にリクエストを投げる際には自動で末尾スラッシュを除去した URL を使う様にできます。
axios/axios: Promise based HTTP client for the browser and node.js#interceptors
/**
* axios を使っているプロジェクト用に加工した axios インスタンスを生成して返す
*/
function createAxiosInstance() {
const instance = axios.create();
// リクエストを加工するインターセプターをセット
instance.interceptors.request.use((config) => {
// URL 末尾のスラッシュを空文字列に置換
config.url = config.url?.replace(/\/$/, '');
return config;
});
return instance;
}
/*
* ↓の様に加工した axios インスタンスを使って通信するようにします。
* これで POST 時に末尾スラッシュ付き URL を使ってもリダイレクトされず期待通りに POST リクエストが飛ぶ様になります。
* これは実際のリクエストが飛ぶ前に↑で書いた URL の変換が機能するためです。
*/
createAxiosInstance().post('/user/');
おそらくこの方法が最も無難に望まぬリダイレクトを防げます。この処理は JavaScript の中で完結するため、ブラウザ等のクライアント側のより低レイヤーな部分もサーバサイドも一切関わらずに適切なリクエストを飛ばせるという点でうれしいことが起きます。しかしながら、この方法に欠点がないわけではありません。axios を介してディレクトリにアクセスしたいのにアクセスできない、という状況の原因特定の妨げになるやもしれません(直のディレクトリアクセスは大抵 403 Forbidden 対象でそもそもアクセスしたい状況が稀ですので、その様な状況はそうそう起きませんが)。