How To Join Relative URLs in JavaScript
I want to join two strings each representing a relative URL in Javascript.
I want to join the base URL http://www.adress.com/more/evenmore
with the following examples:
../../adress
(with the expected output:http://www.adress.com/adress
)../adress
(with the expected outputhttp://www.adress.com/more/adress
)
What would be the bes开发者_JS百科t way? I was thinking of using regexp and checking
how many../
preceed the relative URL, then subtracting that amount from the baseurl and adding them to what is left.8 years later, many browsers (except for Internet Explorer) support the URL constructor (URL(url [, base])
).
> new URL('../address', 'http://www.adress.com/more/evenmore/').href
"http://www.adress.com/more/address"
> new URL('../../address', 'http://www.adress.com/more/evenmore/').href
"http://www.adress.com/address"
The following function decomposes the URL then resolves it.
function concatAndResolveUrl(url, concat) {
var url1 = url.split('/');
var url2 = concat.split('/');
var url3 = [ ];
for (var i = 0, l = url1.length; i < l; i ++) {
if (url1[i] == '..') {
url3.pop();
} else if (url1[i] == '.') {
continue;
} else {
url3.push(url1[i]);
}
}
for (var i = 0, l = url2.length; i < l; i ++) {
if (url2[i] == '..') {
url3.pop();
} else if (url2[i] == '.') {
continue;
} else {
url3.push(url2[i]);
}
}
return url3.join('/');
}
Using URI.js (urijs - npm): absoluteTo()
:
function joinUrl(baseUrl, url) {
var theUrl = new URI(url);
if (theUrl.is("relative")) {
theUrl = theUrl.absoluteTo(baseUrl);
}
return theUrl.toString();
}
The ECMAScript URL
Web API mentioned by @ning is a good place to start: especially as it is available in vanilla JS implementations (Node, etc.) and doesn't require you to use a library that does something the implementation nowq already accomplishes. Consulting the MDN documentation, more specifically the examples, is a great place to start.
Borrowing (somewhat) directly from their documentation:
let m = 'https://developer.mozilla.org';
// ... omitted
let d = new URL('/en-US/docs', m);
If you were to do the above, then console.log
the .toString of the constructed URL
object, your output would be: 'https://developer.mozilla.org/en-US/docs'
.
Importantly, if you consult the Syntax section of the documentation, you will note that the second argument is optional and the second argument (as seen in the above example) represents the base URL (though only in the case of two arguments being supplied).
If both argument values are absolute URLs, Web API honors the first and discards the second.
If you are working with Node.js, I would encourage you to look at the native path module for doing work on relative paths, again over using a library. The main motivation here is that spinning up your own algorithm (probably just a call to path
here and there) is potentially better than introducing a library that will pull in several other dependencies that may introduce vulnerabilities and unnecessary bloat to your application (or just be too heavy weight for what you need).
However, if you are working on the front end, you won't have path
available to you and - as mentioned in @cburgmer's answer comments - Web API's URL
doesn't support the relative path case mentioned. In this case, you may need to look for a library to accomplish this for you; however, again, given the other answers, I'd consider trying out a home-spun approach.
To their credit, URI.js
currently only integrates one non-dev. dependency and doesn't have a huge footprint.
精彩评论