I want to join url href just like path.join, examples
url.join('http://nodejs.org', 'dist', 'download') === 'http://nodejs.org/dist/download'
url.join('http://nodejs.org/dist', 'download') === 'http://nodejs.org/dist/download'
url.resolve('http://nodejs.org/dist', 'download') === 'http://nodejs.org/download'
url.join('http://nodejs.org/dist/', '/download') === 'http://nodejs.org/dist/download'
url.join('http://nodejs.org/dist', 'http://mirror.nodejs.org/dist') === 'http://mirror.nodejs.org/dist'
// without protocol prefix, just like path.join
url.join('nodejs.org', 'dist', 'download') === path.join('nodejs.org', 'dist', 'download') === 'nodejs.org/dist/download'
What do you think about this?
How does this differ from [baseUrl, ...others].join('/')
?
In any case, we are trying to move away from legacy URL APIs like url.resolve()
in favor of the WHATWG standard-compliant API. We probably will not consider this addition.
In some case, others
maybe ['/foo', 'bar/', '/baz/']
. I want path.join('http://nodejs.org', ...others)
to return http://nodejs.org/foo/bar/baz/
. In your code, ['http://nodejs.org', ...others].join('/')
would get http://nodejs.org//foo/bar//baz/
.
BTW, like path.join
. You cannot use [...paths].join(path.sep)
to replace it.
http://nodejs.org//foo/bar//baz/
is a valid URL that may have a different meaning from http://nodejs.org/foo/bar/baz/
. It would be semantically incorrect to disallow this distinction.
There doesn't seem to be anything actionable here as such I'm going to close this.
Use it:
function joinAbsoluteUrlPath(...args: string[]) {
return "/" + args.map( pathPart => pathPart.replace(/(^\/|\/$)/g, "") ).join("/");
}
joinAbsoluteUrlPath("a/b", "/c/d/", "/e", "f/g", "h") // "/a/b/c/d/e/f/g/h"
So, we can't have a function that everybody needs all the time because of semantical correctness?
@waynebloss create RFC for this and refer to it and then it is possible that it will be part of Node built-in function in next few months.
@TimothyGu fyi. here you have use case:
For those that come across this later, consider a combination of url.format({protocol, hostname, port})
and path.posix.join
. If you don't pass a pathname
to format
then you will get exactly the origin of the absolute URL, no trailing slash. Then, you just have to make sure the first token you pass to path.posix.join
has a leading slash. From there, all your arguments to join
can have leading or trailing slashes, no problem.
Been stuck today with this simple issue. Kind of obvious to have resolve, which "resolves" url using all the semantic, but join should be there too, providing different semantic, meaning different function.
Falling back to use urljoin package from the npm.
Our usecase: use base url for CDN and append path to the asset. CDN url can come with or w/o the ending slash.
Have you tried url.format
combined with path.posix.join
as in my previous comment?
@thw0rted we didn't, but I'm sure it works. The problem I have with such a method is, it is too low-levelly to use posix-specific function to calculate URL paths...
Coming from the very different tech stacks and languages, it feels so weird that no one treats node as BE tech, which has a need to provide common library, close or similar to other stacks, so entry-level will be lower, approaches will be same and code review will be easier.
I see that Node tries to provide same API between browser and server, so if browser does not have a function, Node should not have it too. Which is wise. For SSR, SPA.
But Node is not just a platform for SSR.
My solution
path.join(SERVER_URL, imageAbsolutePath).replace(':/','://');
Edit: if you want to support windows enviroments
path.join(SERVER_URL, imageAbsolutePath).replace(/\\/g,'/').replace(':/','://');
The second solution will replace all the backslashes, so url parts like querystring and hash may be altered too, but if you need to join just the url path that's not an issue.
My solution
path.join(SERVER_URL, imageAbsolutePath).replace(':/','://');
Please be careful it does not work on Windows, since path.join
converted /
to \
.
That's why I suggested path.posix.join
in my posts last year -- you're guaranteed the correct behavior regardless of platform.
My 2 cents - it's incredibly ridiculous and overly pedantic if nodejs
libraries cannot provide a proper URL path-joining helper. Yes, technically //
can be in a URL, but 99.99999999% of the time when we construct URLs we do not desire this. Just make a helper that explicitly calls out in its documentation that it doesn't leave in duplicate //
. There, problem solved, you can do anything without violating semantics as long as you document it and are explicit.
Also, for what it's worth, other major languages provide this, e.g. the UriBuilder#path
helper in Java since Java7 has this semantics and leaves out duplicate slashes, and adds slashes if needed - https://docs.oracle.com/javaee/7/api/javax/ws/rs/core/UriBuilder.html (it's not 100% clear from the description, but I have used it much in the past and I know it works that way).
Resorting to file-system helpers is not a good idea... because we are not building file paths! Also, this helper should automatically URL-escape any added path segments.
Url-join npm package: Weekly Downloads - 1,994,766
Most helpful comment
So, we can't have a function that everybody needs all the time because of semantical correctness?