Node.js の URL で相対パスを使いたい
◆ new URL だと相対パスはエラー
◆ 第二引数のベースパスにダミーをつければ動く
◆ url.parse は廃止予定らしい
◆ 第二引数のベースパスにダミーをつければ動く
◆ url.parse は廃止予定らしい
久々に Node.js で Web サーバを作って アクセスしてきた URL をパースしようとしました
昔は url.parse だったのですが 今ではブラウザで使える URL クラスがグローバルにあるようです
なので使ってみたのですが
Invalid URL と言われます
request から取れる情報は 「/」 から始まる相対パスです
自分のオリジン情報なんて不要ですからね
しかし ブラウザにある whatwg 仕様の URL は完全な URL でないとエラーになります
第二引数でベース URL を指定することで相対パスでもオブジェクト化できなくはないのですが 無意味なオリジン情報が含まれてしまいます
origin や hostname プロパティを無視することもできますが 文字列化したときにパス以降だけのプロパティがないので自分で切り捨てる処理が必要になります
新しくてブラウザと互換性のある URL を使おうとしましたが Node.js では Node.js で昔から使われている url.parse を使い続けるべきなんでしょうか
そう思ったのですが 調べてみると
https://github.com/nodejs/node/issues/12682
こんな Issue がありました
同じことを感じてる人は多いようです
url.parse は deprecated になる予定らしく URL を使う場合に相対パスが使えないのは不便だという内容です
相対パスを扱えるクラスを作るとか 使う側でどうにかするとか ライブラリに頼るとかいろいろ意見はあるようですがはっきりこうするとは決まってないみたいです
ですが 中に良さそうな方法があったのでとりあえずこれを使うことにしました
「http://localhost」 などを使うよりそれっぽい感じが出てます
一応デメリットもあると書かれていて それが 「\」 の扱いです
http スキームだと 「\」 もパスの区切り文字と認識されて 「/」 に変換されます
しかし relative のようなスキームでは 「\」 はただの文字の一つです
私は URL に 「\」 が来るような変なケースを扱うつもりはないのでとりあえず relative にしましたが こういうケースも http と同様に扱わないといけないなら http から始まるダミーのオリジンを作ることになると思います
ブラウザでもこれが面倒なので もう URL が対応してくれればいいのですけど 区切り文字の違いとか http の URL なのか file スキームのローカルなのかとか相対パスを扱うのは難しいとかで何度か提案はあっても URL は完全なパスしか対応しないみたいなことになってるそうです
request の URL を分割するみたいな Node.js のすごく基本的な機能くらい簡単に扱えるようにしてほしいですね
昔は url.parse だったのですが 今ではブラウザで使える URL クラスがグローバルにあるようです
なので使ってみたのですが
new URL(req.url)
Invalid URL と言われます
request から取れる情報は 「/」 から始まる相対パスです
自分のオリジン情報なんて不要ですからね
しかし ブラウザにある whatwg 仕様の URL は完全な URL でないとエラーになります
第二引数でベース URL を指定することで相対パスでもオブジェクト化できなくはないのですが 無意味なオリジン情報が含まれてしまいます
origin や hostname プロパティを無視することもできますが 文字列化したときにパス以降だけのプロパティがないので自分で切り捨てる処理が必要になります
新しくてブラウザと互換性のある URL を使おうとしましたが Node.js では Node.js で昔から使われている url.parse を使い続けるべきなんでしょうか
そう思ったのですが 調べてみると
https://github.com/nodejs/node/issues/12682
こんな Issue がありました
同じことを感じてる人は多いようです
url.parse は deprecated になる予定らしく URL を使う場合に相対パスが使えないのは不便だという内容です
相対パスを扱えるクラスを作るとか 使う側でどうにかするとか ライブラリに頼るとかいろいろ意見はあるようですがはっきりこうするとは決まってないみたいです
ですが 中に良さそうな方法があったのでとりあえずこれを使うことにしました
new URL('/foo/bar', 'relative:///');
「http://localhost」 などを使うよりそれっぽい感じが出てます
一応デメリットもあると書かれていて それが 「\」 の扱いです
http スキームだと 「\」 もパスの区切り文字と認識されて 「/」 に変換されます
しかし relative のようなスキームでは 「\」 はただの文字の一つです
new URL("http://a/b/c\\d/e").href
// "http://a/b/c/d/e"
new URL("relative://a/b/c\\d/e").href
// "relative://a/b/c\d/e"
私は URL に 「\」 が来るような変なケースを扱うつもりはないのでとりあえず relative にしましたが こういうケースも http と同様に扱わないといけないなら http から始まるダミーのオリジンを作ることになると思います
new URL("/foo/bar", "http://RELATIVE/").href
// "http://relative/foo/bar"
ブラウザでもこれが面倒なので もう URL が対応してくれればいいのですけど 区切り文字の違いとか http の URL なのか file スキームのローカルなのかとか相対パスを扱うのは難しいとかで何度か提案はあっても URL は完全なパスしか対応しないみたいなことになってるそうです
request の URL を分割するみたいな Node.js のすごく基本的な機能くらい簡単に扱えるようにしてほしいですね