Skip to content

Instantly share code, notes, and snippets.

@Ciantic
Forked from Yaffle/URLUtils.js
Created September 30, 2011 15:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Ciantic/1254025 to your computer and use it in GitHub Desktop.
Save Ciantic/1254025 to your computer and use it in GitHub Desktop.
Parse URI and Convert Relative URI to Absolute
var parseURIMatcher = /^([^:\/?#]+:)?(\/\/(?:[^:@]*(?::[^:@]*)?@)?(([^:\/?#]*)(?::(\d*))?))?([^?#]*)(\?[^#]*)?(#[\s\S]*)?/;
/**
* Parses the URI
*
* @param url
* @returns object
*/
function parseURI(url) {
var m = parseURIMatcher.exec(url);
// authority = '//' + user + ':' + pass '@' + hostname + ':' port
return (m ? {
href : m[0] || '',
protocol : m[1] || '',
authority: m[2] || '',
host : m[3] || '',
hostname : m[4] || '',
port : m[5] || '',
pathname : m[6] || '',
search : m[7] || '',
hash : m[8] || ''
} : null);
}
/**
* Absolutizes the path in `href` based on `base` url.
*
* @param base Base URI
* @param href Path which to convert absolute
*
* @returns Absolute URI
**/
function absolutizeURI(base, href) {// RFC 3986
function removeDotSegments(input) {
var output = [];
input.replace(/^(\.\.?(\/|$))+/, '')
.replace(/\/(\.(\/|$))+/g, '/')
.replace(/\/\.\.$/, '/../')
.replace(/\/?[^\/]*/g, function (p) {
if (p === '/..') {
output.pop();
} else {
output.push(p);
}
});
return output.join('');
}
href = parseURI(String(href || '').replace(/^\s+|\s+$/g, ''));
base = parseURI(String(base || '').replace(/^\s+|\s+$/g, ''));
if (href === null || base === null) {
return null;
}
var res = {};
if (href.protocol || href.authority) {
res.authority = href.authority;
res.pathname = removeDotSegments(href.pathname);
res.search = href.search;
} else {
if (!href.pathname) {
res.pathname = base.pathname;
res.search = href.search || base.search;
} else {
if (href.pathname.charAt(0) === '/') {
res.pathname = removeDotSegments(href.pathname);
} else {
if (base.authority && !base.pathname) {
res.pathname = removeDotSegments('/' + href.pathname);
} else {
res.pathname = removeDotSegments(base.pathname.slice(0, base.pathname.lastIndexOf('/') + 1) + href.pathname);
}
}
res.search = href.search;
}
res.authority = base.authority;
}
res.protocol = href.protocol || base.protocol;
res.hash = href.hash;
return res.protocol + res.authority + res.pathname + res.search + res.hash;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment