はじめに
JavaScriptのURLコンストラクタを使っているときに、初歩的なミスにハマってしまったので、備忘として残しておきます。
何が起きたか
ある場所においてあるファイル名を取得する処理を以下のように記述していました。
const base = "http://example.com/test.pdf";
const url = new URL(base);
const fileName = url.pathname.split("/").pop();
console.log(fileName); // test.pdfと出力される
一見なんの問題もないように見えますが、日本語ファイル名が入ってくると様子が変わってきます。
const base = "http://example.com/テスト.pdf";
const url = new URL(base);
const fileName = url.pathname.split("/").pop();
console.log(fileName); // %E3%83%86%E3%82%B9%E3%83%88.pdfと出力される
それもそのはずで、URLコンストラクタは引数で渡された文字列をエンコードしてURLオブジェクトを返します。
上記ページにも
URL は、RFC 3986 にあるルールに従ってエンコードされます。
と記載されています。
どのように対処したか
単純にデコードすればよいだけなので、以下のようにしました。
const base = "http://example.com/テスト.pdf";
const url = new URL(base);
const fileName = decodeURIComponent(url.pathname.split("/").pop());
console.log(fileName); // テスト.pdfと出力される
まとめ
蓋をあければなんてことのない話ですが、この現象に遭遇したときは結構テンパりました。
もともと別の処理で書いていたものを、URLコンストラクタを使用して書き換えた際にこの事象が発生していたのですが、運の悪いことに(?)別の処理でURLのエンコード/デコードを行うロジックを記載していたために、その修正による影響なのでは、というところで混乱が発生していました。
まったく関係ない場所での処理なのに、なぜ影響が起きたのか、というところで調査が難航していたのですが、実際には全然関係ない修正が原因だった、というオチでした。
修正対応する場合には、根本原因をきちんと見極めることが大事ですね