Is this safe to use require(\"path\").join
to concatenate URLs, for example:
require(\"path\").join(\"http://example.com\", \"ok\");
//returns
By the time posting this answer url.resolve()
is deprecated;
I did following to join to path in Nodejs:
const path = require('path');
const url = require('url');
let myUrl = new URL('http://ignore.com');
myUrl.pathname=path.join(firstpath, secondpath);
console.log(myUrl.pathname)
This approach logs correct url path and it works for my case.
What is your opinion about this approach?
Thanks
This can be accomplished by a combination of Node's path and URL:
const nodeUrl = require('url')
const nodePath = require('path')
> const myUrl = new nodeUrl.URL('https://example.com')
pathname=
and path.join
to construct any possible combination:> myUrl.pathname = nodePath.join('/search', 'for', '/something/')
'/search/for/something/'
(you can see how liberal path.join
is with arguments)
> myUrl.toString()
'https://example.com/search/for/something/'
This technique uses built-in libraries. The less third-party dependencies the better, when it comes to CVEs, maintenance, etc.
When I review code I'm adamant about never manipulating URLs as strings manually. For one, look how complicated the spec is.
Secondly, the absence/presence of a trailing/prefixed slash (/
) should not cause everything to break! You should never do:
const url = `${baseUrl}/${somePath}`
and especially not:
uri: host + '/' + SAT_SERVICE + '/' + CONSTELLATION + '/',
Of which I have seen.
The WHATWG URL object constructor has a (input, base)
version, and the input
can be relative using /
, ./
, ../
. Combine this with path.posix.join
and you can do anything:
const {posix} = require ("path");
const withSlash = new URL("https://example.com:8443/something/");
new URL(posix.join("a", "b", "c"), withSlash).toString(); // 'https://example.com:8443/something/a/b/c'
new URL(posix.join("./a", "b", "c"), withSlash).toString(); // 'https://example.com:8443/something/a/b/c'
new URL(posix.join("/a", "b", "c"), withSlash).toString(); // 'https://example.com:8443/a/b/c'
new URL(posix.join("../a", "b", "c"), withSlash).toString(); // 'https://example.com:8443/a/b/c'
const noSlash = new URL("https://example.com:8443/something");
new URL(posix.join("./a", "b", "c"), noSlash).toString(); // 'https://example.com:8443/a/b/c'
This is what I use:
function joinUrlElements() {
var re1 = new RegExp('^\\/|\\/$','g'),
elts = Array.prototype.slice.call(arguments);
return elts.map(function(element){return element.replace(re1,""); }).join('/');
}
example:
url = joinUrlElements(config.mgmtServer, '/v1/o/', config.org, '/apps');
There are other working answers, but I went with the following. A little path.join/URL combo.
const path = require('path');
//
const baseUrl = 'http://ejemplo.mx';
// making odd shaped path pieces to see how they're handled.
const pieces = ['way//', '//over/', 'there/'];
//
console.log(new URL(path.join(...pieces), baseUrl).href);
// http://ejemplo.mx/way/over/there/
// path.join expects strings. Just an example how to ensure your pieces are Strings.
const allString = ['down', 'yonder', 20000].map(String);
console.log(new URL(path.join(...allString), baseUrl).href);
// http://ejemplo.mx/down/yonder/20000
Axios has a helper function that can combine URLs.
function combineURLs(baseURL, relativeURL) {
return relativeURL
? baseURL.replace(/\/+$/, '') + '/' + relativeURL.replace(/^\/+/, '')
: baseURL;
}
Source: https://github.com/axios/axios/blob/fe7d09bb08fa1c0e414956b7fc760c80459b0a43/lib/helpers/combineURLs.js