In JavaScript, there seems to be some restrictions when changing the protocol of a given URL when using the URL
object. However, I can't find where this behaviour is documented (URL
, URL.prototype.protocol
) or why it would be intended for it to work like that.
Can anyone shine some light on this?
EDIT: The behaviour seems to be inconsistent across JS runtimes. Firefox, Node and Deno all "refuse" to change the protocol, but Chrome, Safari and Bun all "comply" with the change…
const url1 = new URL('http://example.com')
console.log(url1.protocol) // http:
url1.protocol = 'https:'
console.log(url1.protocol) // https:
const url2 = new URL('webcal://example.com')
console.log(url2.protocol) // webcal:
url2.protocol = 'https:'
console.log(url2.protocol) // webcal:, but should be https:
This is documented for Node.js:
The WHATWG URL Standard considers a handful of URL protocol schemes to be special in terms of how they are parsed and serialized. When a URL is parsed using one of these special protocols, the
url.protocol
property may be changed to another special protocol but cannot be changed to a non-special protocol, and vice versa.For instance, changing from
http
tohttps
works: […]However, changing from
http
to a hypotheticalfish
protocol does not because the new protocol is not special. […]Likewise, changing from a non-special protocol to a special protocol is also not permitted: […]
According to the WHATWG URL Standard, special protocol schemes are
ftp
,file
,http
,https
,ws
, andwss
.
(emphasis and ellipsis mine)
Your webcal
protocol is not in that list, so you cannot change it to https
.
The intention of distinguishing special from non-special URLs appears to be that their hostname should be parsed differently, e.g. requiring valid domain names. That makes switching protocols a hazard if the hostname of the existing URL does not satisfy the requirements of the new protocol.
For Node.js, this is implemented by the C++ Ada URL library. Deno uses the Rust urlpattern crate. Firefox already changed their implementation to comply with the spec, Chrome followed just recently and will release this with M118. The Webkit (Safari, Bun) bug report is still open.
Still, this is bonkers, and there is a specification issue opened in 2021 to allow this. There also might be web compatibility issues with this restriction, so they may have to adjust the spec instead. However, it appears that the current plan is to follow through with it, and instead add a constructor for creating a new URL
from parts.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With