htmlrubyurlrfc3986

How is an a tag with href="./etc" resolved? Chrome not adhering to RFC 3986?


If I'm on a site example.com/foo/index.html, and there is an a tag with href ./bar/test.html, I expect the URL of the linked document to be example.com/foo/bar/test.html. However, in web browsers such as Chrome or Firefox, this behavior seems to be different, and it resolves to example.com/bar/test.html.

I thought, ./ means the current directory, in this case example.com/foo/

Real life example: On https://www.salzburger-landestheater.at/de/spielplan/index.html, there is this a tag:

<a href="./produktionen/shakespeare-im-park-golden-lads-amp-girls.html?ID_Vorstellung=5527&amp;m=3">Shakespeare im Park: Golden Lads &amp; Girls</a>

If clicking on the link, Chrome sends me to https://www.salzburger-landestheater.at/de/produktionen/shakespeare-im-park-golden-lads-amp-girls.html?ID_Vorstellung=5527&m=3, which is the correct location. However, I would have expected the link to be https://www.salzburger-landestheater.at/de/spielplan/produktionen/shakespeare-im-park-golden-lads-amp-girls.html?ID_Vorstellung=5527&m=3

When using for example Ruby, it outputs the URL I expected (which, sadly, leads to a 404 page though):

URI.join("https://www.salzburger-landestheater.at/de/spielplan/index.html", "./produktionen/shakespeare-im-park-golden-lads-amp-girls.html?ID_Vorstellung=5527&m=3").to_s
=> "https://www.salzburger-landestheater.at/de/spielplan/produktionen/shakespeare-im-park-golden-lads-amp-girls.html?ID_Vorstellung=5527&m=3"

I guess Chrome does it correctly, but I really don't understand it; isn't /spielplan/ the current directoy referenced with ./? Can someone point me to an official documentation? I've found the RFC 3986, Section 5.4.1, which gives following example:

Within a representation with a well defined base URI of

http://a/b/c/d;p?q

a relative reference is transformed to its target URI as follows.

[...]

"./g" = "http://a/b/c/g"

For reference, the RFC example works in Ruby as expected:

> URI.join("http://a/b/c/d;p?q", "./g").to_s
=> "http://a/b/c/g"

Solution

  • I actually just realized the issue in my "real life" example. I keep the question online in case anyone stumbles upon a similar issue.

    The document https://www.salzburger-landestheater.at/de/spielplan/index.html defines a base: <base href="https://www.salzburger-landestheater.at/de/">

    Thus, ./produktionen/shakespeare-im-park-golden-lads-amp-girls.html?ID_Vorstellung=5527&amp;m=3 correctly resolves to base_url + href: https://www.salzburger-landestheater.at/de/produktionen/shakespeare-im-park-golden-lads-amp-girls.html?ID_Vorstellung=5527&amp;m=3