JavaScript URI Objects

I started looking at a dashcode project the other day. Within a few minutes, I realised that I needed something like, in order to resolve URIs into an absolute form. I had a quick look around and there didn’t seem to be anything code out there that does this.

So, I had a quick look at RFC 3986 and noticed that amongst other things it contains pseudo-code for parsing and resolving URLs. I coded it up first in Ruby, which took the pseudo-code almost word for word, and made some tests for it. Then I translated into JavaScript and figured out how to use Test.Simple.

The end result is js-uri, a small URI object. It does what I need at the moment.

  // Parsing.
  var some_uri = new URI("");
  alert(some_uri.authority); //
  alert(some_uri);           //

  // Resolving.
  var blah      = new URI("blah");
  var blah_full = blah.resolve(some_uri);
  alert(blah_full);         //

There’s quite a bit it doesn’t do yet.

  • %-escaping and unescaping.
  • Parsing the URL in more detail. It would be useful to pull out the query parameters and host / port for instance.
  • For some reason, the tests only work in Firefox. Not sure why.

But hopefully it’s still useful.

In the process of developing the JavaScript, I spent ages tracking down one particular problem. I was trying to introduce new scope to define a couple of private helper functions:

  (function () {
      function merge(base, rel_path) { ... }

      function remove_dot_segments(path) { ... }

      URI.prototype.resolve = function (base) {
          var target = new URI();
          // ...
          return target;

Looks perfectly legit right? It caused syntax errors in every browser I tried. Eventually, JSLint managed to tell me the problem: a missing semicolon after the URI.prototype.resolve definition. I hate JavaScript for trying to guess where the semicolon should go. Because it can get it so wrong like this.

8 replies on “JavaScript URI Objects”

This is excellent. I’ve half written chunks of this so often in Zimki that I’ve been meaning to write a reusable version myself. Maybe I should modify your version to be useful for that.

Couple of points…firstly, can you make this free software by any chance? I don’t know if you meant to, but there’s no license that I can see attached.

Secondly…when are you going to get a chance to implement parameter handling? Do you want me to have a go?

My pet peeve with JavaScript is that trailing commas (for example, in list declarations) can cause problems. Of course this is runtime dependent; it’s fine in Zimki but I think both IE and Safari can get kvetchy over it.

It wouldn’t be such a problem but years of Perl have conditioned me to leave trailing commas, so that expanding the list never goes wrong.

Hi Dominic,

I have a slightly simplistic implementation of the URI object (though it does the same job) here:

Example here:

My version doesn’t have the resolve function – since I was just seeing if the functionality could be quickly replicated using the DOM. On the same note, I don’t know how this would work within Dashboard – whether the widget has a DOM (though I assume it does).

It does uses the DOM to form the parts of the URI (i.e. if you create URI it will pre-load the other values from the current window.location) – but I’ve also have a query object that you can query individual parts or change and add elements to the query string, i.e. change ?page=1 to ?page=2&subpage=a

var u = URI('');
// shows
// ...also = 10;
// shows

Totally aside, not sure if you remember me, but you interviewed me a little over a year ago – I tried to reply to your email to no avail as it kept bouncing.

Mark: It should be BSD licensed. It’s at the top of URI.js, but I’ll make it more explicit. I’m going to have a go at parsing the query string properly over the weekend, check back on Monday. Warning: I think I’ll need to go to accessors instead of properties, though.

Paul: Yup, it’s a pain in the arse. More annoying is the fact that I can’t get the tests to run in Safari / Opera. Looks like a JSAN problem, but I haven’t gone into it closely.

Remy: Apologies—my google-fu must have missed that. The resolve() function was the real reason for writing it. Dashboard does have a proper DOM, but I couldn’t find a way of doing this whilst browsing through my rhino book. But I’d prefer to avoid depending on the DOM, as I will probably end up using this as part of FlowScript.

Anybody: If you want to hack on it, let me know your gmail id and I’ll add you to the project as a committer.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s