URLのパースを各言語で行った時の挙動の違い
URLをパースしていて不可思議な現象に立ち会ったので紹介します。
プログラムを書いていて、URLをパースしなければいけない機会というのは結構存在すると思います。
PythonとJavaScript両方で同じURLをパースしたら片方でエラーが出て、片方ではうまくいくといった現象が起こりました。
それぞれの言語ではどうなんだろう?と思って4種類程度の言語で確かめてみました。
実験方法
至ってシンプルで、
URL1 http://saruhei1989.hatenablog.com/
URL2 //saruhei1989.hatenablog.com/
の上記2リンクを用意して、それぞれを各言語でパースするだけです。
URL2はプロトコルを省略したものです。一応aタグのsrc
に指定したら両方正しく遷移するものを用意しました。
ご想像の通り、僕が遭遇した不可思議パターンのURLです。
結果
言語 | URL1 | URL2 | URLの定義 |
---|---|---|---|
Python | パースされる | パースされる | RFC3986 |
JavaScript | パースされる | エラーが出る | RFC3986, RFC3987 |
PHP | パースされる | パースされる | RFC3986 |
Ruby | パースされる | パースされる | RFC3986, RFC3987 |
Pythonの公式ドキュメント : https://docs.python.org/ja/3/library/urllib.parse.html
JavaScriptは公式が見つからなかったので仕様の記載しているもの : https://developer.mozilla.org/ja/docs/Web/API/URL/URL
PHPの公式ドキュメント : https://www.php.net/manual/ja/function.parse-url.php
Rubyの公式ドキュメント : https://docs.ruby-lang.org/ja/latest/class/URI.html
結論はJavaScriptだけエラーがでました。
言語が違うもの、違ってもおかしくないという話ですが、 RubyとJavaScriptはURLの定義どころか、実装の際に利用した仕様が全く一緒のようです。
考察
英語が難しすぎて全然理解が進まなかったのですが、 用意したURLは両方RFC3986の仕様を満たすURLではあるようです。
結論どっちが正しいとか全然わからなかったのですが、言えることは
違う言語をまたいで同じだと思われる処理をするのはやめましょう
ということですね。