Jesper Larsen-Ledet
Jesper Larsen-Ledet

Reputation: 6723

making relative url absolute using arbitrary root in javascript

Assuming that I'm on a page on a different domain (mydomain.com) and that the relative url only exists in code (not in the DOM)

How do I combine two arbitrary urls entirely in javascript?

var a = 'http://example.com/some/path/';
var b = '../other/path/';
var c = magicUrlCombine(a,b);
assert(c == 'http://example.com/some/other/path/');

It should also work for

var a = 'http://example.com/some/path/';
var b = 'http://pink-unicorns.com/some/other/path/';
var c = magicUrlCombine(a,b);
assert(c == 'http://pink-unicorns.com/some/other/path/');

EDIT:

I'm looking for a completely general function for combining an absolute url with an arbitrary url. The same logic as the browser uses for resolving links but for urls that are not in the HTML of the page and/or not relative to the current location.href.

var a = 'http://example.com/a/b/c/';
var b = '../d/e/';
assert(c == 'http://example.com/a/b/d/e/')

OR

var b = '/f/g/';
assert(c == 'http://example.com/f/g/')

OR

var b = 'http://jquery.com/h/i/';
assert(c == 'http://jquery.com/h/i/')

EDIT 2:

node.js has a url module that has the right functionality, but I haven't found a nice way of reusing it on the client side. (how to use node.js module system on the clientside)

I managed to hack my way through making it work but it's not really a solution I feel comfortable putting into a production site. Hackety hack

Upvotes: 5

Views: 1803

Answers (5)

closedloop
closedloop

Reputation: 711

I have used on the server side, using NodeJS,

var url = require('url');
url.resolve(from, to);

in your case:

var a = 'http://example.com/some/path/';
var b = '../other/path/';
var c = url.resolve(a, b);
assert(c == 'http://example.com/some/other/path/');

var a = 'http://example.com/some/path/';
var b = 'http://pink-unicorns.com/some/other/path/';
var c = url.resolve(a, b);
assert(c == 'http://pink-unicorns.com/some/other/path/');

Upvotes: 2

Jesper Larsen-Ledet
Jesper Larsen-Ledet

Reputation: 6723

JQuery Mobile has it

$.mobile.path.makeUrlAbsolute(relPath, absPath)

console.log($.mobile.path.makeUrlAbsolute('../d/e/', 'http://example.com/a/b/c/'));
console.log($.mobile.path.makeUrlAbsolute('/f/g/', 'http://example.com/a/b/c/'));
console.log($.mobile.path.makeUrlAbsolute('http://jquery.com/h/i/', 'http://example.com/a/b/c/'));

all give the expected results

Upvotes: 2

Thor Jacobsen
Thor Jacobsen

Reputation: 8851

This is a possible, but untested, solution:

function magicCombine(a,b){
    if(b.indexOf('://') != -1) return b;

    var backs = 0;
    var lastIndex = b.indexOf('../');

    while(lastIndex != -1){
        backs++;
        lastIndex = b.indexOf('../', lastIndex+3);
    }

    var URL = a.split('/');
    //Remove last part of URL array, which is always either the file name or [BLANK]
    URL.splice(URL.length-1, 1)

    if(b.substr(0,1) == '/')
        b = b.substr(1);
    var toAdd = b.split('/');

    for(var i = 0, c = toAdd.length-backs; i < c; ++i){
        if(i < backs)
            URL[URL.length - (backs-i)] = toAdd[backs+i];
        else
            URL.push(toAdd[backs+i]);
    }

    return URL.join('/');
}

Should take care of both cases...

Upvotes: 1

mplungjan
mplungjan

Reputation: 177860

I assumed I understood the question but my fiddle returns two false. The examples are not obvious

http://jsfiddle.net/mplungjan/z5SUn/

function magicUrlCombine(a,b) {
  var linkA = document.createElement('a');
  linkA.href = a;
  var linkB = document.createElement('a');
  linkB.href = b;
  return linkB.href.replace(linkB.host,linkA.host)
}

Upvotes: 1

David
David

Reputation: 8650

Couldn't resist having a go at a solution

var magicUrlCombine = function(a,b){
   return (a + b).replace(/[\w\-\.]+\/..\/|\:\/\/[\w\-\.\/]+http/g,'');
}

works for both test cases and combinations of the two

http://jsfiddle.net/8HLeQ/2/

Upvotes: 1

Related Questions