- From: Livia Medeiros <notifications@github.com>
- Date: Thu, 11 Sep 2025 12:47:41 -0700
- To: whatwg/url <url@noreply.github.com>
- Cc: Subscribed <subscribed@noreply.github.com>
- Message-ID: <whatwg/url/issues/879@github.com>
LiviaMedeiros created an issue (whatwg/url#879) ### What is the issue with the URL Standard? ## To put it shortly `new URL('file:a/b')`, `new URL('file:./a/b')`, `new URL('file:../a/b')` should be `URL` objects with absolute URLs resolved using current context. Currently, the spec considers it to have [`special-scheme-missing-following-solidus`](https://url.spec.whatwg.org/#special-scheme-missing-following-solidus) validation error and implicitly resolves it against `/`. ## Problem According to [RFC 3986](https://www.rfc-editor.org/rfc/rfc3986.html) and [RFC 8089](https://www.rfc-editor.org/rfc/rfc8089.html), a `file:` URI that doesn't start with `/` or `//` must be treated as relative-path reference. In the context of these RFCs, it's meaningful only in relative resolution algorithms, paired with the base URI (absolute). When base URI is explicitly provided, ``new URL(`file:${relativePath}`, base)`` is same as ``new URL(relativePath, base)``. However, when base is not provided, it seems that neither RFCs nor WHATWG URL spec explicitly defines what to do. This leads to unexpected (and I think, undesired) implementation-specific results. ## What implementations do `new URL('file:a/b')` Firefox (v142.0.1): ```js host: "" href: "file:///a/b" origin: "null" pathname: "/a/b" ``` Chrome (v140.0.7339.80): ```js host: "a" href: "file://a/b" origin: "file://" pathname: "/b" // but new URL('file:./a/b') host: "." href: "file://./a/b" origin: "file://" pathname: "/a/b" ``` Node.js (v24.7.0): ```js host: "", href: "file:///a/b", origin: "null", pathname: "/a/b", ``` ## Why relative `file:` URL matters Relative filepaths are used everywhere. Relative URL with `file:` schema is a clear, unambiguous way to refer to a file in similar way. There are at least two use cases for them: 1. (Potentially standartized one day) `fetch('file:...')`. `fetch` expects URL object or urlstring, and relative urlstrings would be very useful. Resolving them against root is a footgun. 1. There were multiple occasions where people wanted `node:fs` functions to accept urlstrings (detected if starting with `file:`) along with path strings and URL objects, or to allow `node file:///path/to/file.js`. This can not be implemented directly (because it's ambiguous when path strings are accepted) but the demand exists, and so do userland implementations. In the latest versions of Node.js, `node --entry-url file:relative/path/to/file.js?canHave=searchParams#andHashString` is already resolved against CWD. I'm not aware of any use cases for relative `file:` URLs intentionally being resolved against root. ## Proposal I think, the WHATWG URL objects built from relative references should be defined as result of relative resolution, using current context as base URI. In browsers, `new URL('file:relativePath')` must be equal to `new URL('file:relativePath', document.location.href)`. In non-browsers, `new URL('file:relativePath')` must be equal to `new URL('file:relativePath', cwdURL)`, where `cwdURL` is an absolute `file:` URL pointing to current working directory with trailing slash (example: cwdPath `/home/livia` translates to cwdURL `file:///home/livia/`). In browsers, this would be aligned with the resolutions in HTML. `<a href="file:a/b">` points to `a/b` relative to current location. In non-browsers, this would be aligned with the resolution in path strings. `node:path.resolve("a/b")` resolves against CWD, and in most cases relative paths are resolved against it implicitly. ## Additional info The spec should provide example(s) with `file:` URI without leading slashes and explicitly state that these are relative paths (not absolute with implicit root, and not auth-path with host). Unless I'm missing some edge cases, parsing *any* `file:` URL can be done using the relative resolution algorithm, since in case of absolute URL the base would be ignored anyway. Maybe the actual implementations should have fast-path when the URL is absolute, but in the spec the patch might be straightforward. In the [4.4. URL parsing](https://url.spec.whatwg.org/#url-parsing): 1. When we enter [file state](https://url.spec.whatwg.org/#file-state), if `base` is null, set `base` to the *[bikeshedded term for the "current context" URI]* 1. Add definition of current context, which in browsers should be URL of the document and in non-browsers should be CWD. 1. (Optional) If for whatever implementation-and-platform-specific reason current context can not be used, the spec can explicitly define `file:///` as fallback value instead of null. 1. (Optional) In [scheme state](https://url.spec.whatwg.org/#scheme-state) step 2-5, remove the "If [remaining](https://url.spec.whatwg.org/#remaining) does not start with "//", [special-scheme-missing-following-solidus](https://url.spec.whatwg.org/#special-scheme-missing-following-solidus) [validation error](https://url.spec.whatwg.org/#validation-error)." step. Per RFCs relative path without `//` is valid. -- Reply to this email directly or view it on GitHub: https://github.com/whatwg/url/issues/879 You are receiving this because you are subscribed to this thread. Message ID: <whatwg/url/issues/879@github.com>
Received on Thursday, 11 September 2025 19:47:45 UTC