Edited at

トリビア: location.port = undefined すると port が 0 になるのなんでだろう

https://twitter.com/ninjinkun/status/1059300775413743616

自分も気になったので調べてみた。

結論を先に書くと、どうやら 共通の仕様はないがブラウザ同士の後方互換性によってこのような暗黙のルールになっている ということっぽい。


まずは実際にやってみた

要素を検証 (Inspect Element) でコンソールを開き、 location.port = undefined と代入してみる。






どのブラウザで発生するか

手元にあった


  • Google Chrome (Version 70.0.3538.102 (Official Build) (64-bit)

  • Firefox Quantum (63.0.3 (64-bit))

  • Safari Version 12.0.1 (14606.2.104.1.1)

ではそのような動作になった。


undefined 以外ではどうか


  • location.port = 'Hello, World!'


:0 になったもの


  • location.port = null

  • location.port = 'Hello, World!'

  • location.port = alert

  • location.port = 'Hello, World!'

どうやら数値として解釈できない場合には :0 になるっぽい。


明文化された仕様にはないっぽい

にもみつけられなかった。

どこかにはあるかもしれないが、少なくとも kitsuyui にはみつけられなかった。


ソースコードを追う

しかたがないので Chromium のソースコードを追うと ParsePortFromStringPosition という箇所に該当の処理があった。 https://github.com/chromium/chromium/blob/146802d392d308b084a472f363da971be7956e3c/third_party/blink/renderer/platform/weborigin/kurl.cc#L466-L474

while (IsASCIIDigit(value[port_end]) && port_end < length)

++port_end;
while (value[port_start] == '0' && port_start < port_end - 1)
++port_start;

// Required for backwards compat.
// https://www.w3.org/Bugs/Public/show_bug.cgi?id=23463
if (port_start == port_end)
return "0";

コメントにあったチケット https://www.w3.org/Bugs/Public/show_bug.cgi?id=23463 を追ってみると、今回の問いと同様の質問をしているユーザがいる。 Webkit / Blank ともに Gecko (つまり Firefox) に合わせているのでこうなっている、という回答が見つかる。


では Firefox はいつからこのような挙動なのか ?

Firefox のソースも追ってみる。

これをひたすら遡って、いつからそうなっているのかみてみよう。

(途中でリファクタによってファイル名が変わっているので、 GitHub 上で遡るのはちょっと苦労するかもしれない。 git clone してコマンドで探す方が楽だろう。)

https://github.com/mozilla/gecko-dev/blame/50187fd7d034ca79bf8d51c0b5014140a3e69b73/dom/src/base/nsLocation.cpp#L381-L388

日付をみると 1998 年。なのでおそらく Netscape がオープンソース化された当初にはこのような挙動だったらしい。

C の標準ライブラリ関数 atol でシンプルに変換しているだけなので、変換に失敗しても 0 を返す (というよりも errorno を更新しないし失敗という概念が atol にはない) 、ということになっていたわけだ。実に単純な話だった。

これが現代でも暗黙の仕様として各種のブラウザに実装されているというわけだ。


他の太古のブラウザでは……?

他の旧いブラウザの挙動もみてみたかったが、手元には環境がない。

同じ時代の Internet Explorer ではどのような挙動になるか、などなど興味は尽きない。

残念ながら手元に 1998 年の Internet Explorer がないのでここで調査は打ち切りにする。