I am trying to figure out why there is a difference between two identical URL constructor calls in Safari and Chrome
Here is the example from Safari:
And here is an example from Chrome:
I'm working on an application that embeds inside a webview for various mobile platforms such as Android and Ios. This behavior of the URL constructor creates problems.
As you can in the chrome pathname includes localhost which is incorrect, the hostname and host are also empty, in safari everything seems fine
I was trying to set up manifest.json locally to test is there a way to control this behavior by registering custom URL schema, also I was trying to play with navigator.registerProtocolHandler
, here is the link to the docs.
This is not really a problem with the URL constructor. The problem is actually with the argument that has been provided to the constructor.
As you probably already know, JavaScript is quite a hacky language. Rather than being very strict and uptight, it tries to handle everything as gracefully as possible rather than throwing an exception (that's why we have tons of terrible JavaScript developers).
test
is not an actual protocolThe first issue is that test://
is not an actually a protocol. However, the URL
constructor doesn't really care because people make up new protocols every single day. Because of this, URL
will accept test://
as a valid protocol
This is where the difference between a URI and a URL come into play. A URI can have any format as the hostname (after the protocol, ://
, and before the path, /
).
With a URL, the hostname must contain the domain name (google
) and the top-level domain (.com
). There are some URLs, like yours, that don't include a top-level domain. In the case that you are using localhost
, you should also include a port number (:3000
or :8080
or something like that).
If you try the following, then you will notice that they have identical implementations:
new URL('https://localhost:3000/my/path?query=my+query')