9

I'm building a JS library which has a requirement of looking at form[action] and a[href] values and resolving them into absolute URLs.

For example, I'm on http://a/b/c/d;p?q and encounter an href value of "../g" (assume there's no <base> element). The resulting absolute would be: http://a/b/g.

Is there a JS library that does this already? I'd have to believe so.

For more info about what's needed, the spec: https://www.rfc-editor.org/rfc/rfc3986#section-5.4

Community
  • 1
  • 1
Jeremy Dunck
  • 5,724
  • 6
  • 25
  • 30

4 Answers4

23

In modern browsers and node, the built-in URL constructor handles this:

u = (new URL("?newSearch",
             "http://a.example/with/a/long/path.file?search#fragment")).href

(yields http://a.example/with/a/long/path.file?newSearch)

If you want the base to be relative to the current document, you can do that explicitly:

u = (new URL("?newSearch", document.location)).href

In addition to .href, the URL object also gives you access to all of the URL components (protocol, host, path, search, hash, etc.).

Going back (from absolute URLs to relative URLs) takes some code.

ericP
  • 1,675
  • 19
  • 21
21

It turns out that the .href attribute of a A element (not .getAttribute('href'), but .href) returns the resolved (absolute) URL.

Mark Amery
  • 143,130
  • 81
  • 406
  • 459
Jeremy Dunck
  • 5,724
  • 6
  • 25
  • 30
  • 2
    In other words, the *DOM property* (accessed via `someAnchorElement.href`) returns the resolved URL, and the *HTML attribute* (accessed via `someAnchorElement.getAttribute('href')` or `someAnchorElement.attributes.href`) returns it as originally written in the HTML. (Well, even that isn't 100% true, but Googling 'prop vs attr' will throw up plenty of relevant discussion.) – Mark Amery Jun 30 '13 at 13:19
  • Exactly you don't need a library to do this. – tusharmath Jun 30 '13 at 13:32
1

Nice pure JS solution that works without DOM: https://gist.github.com/1088850 (works everywhere but especially useful for server side JS).

Konstantin Smolyanin
  • 17,579
  • 12
  • 56
  • 56
1

The JavaScript URL constructor handles relative urls. So in your case:

    new URL("../g", "http://a/b/c/d;p?q").href

    // returns "http://a/b/g"
Luca Fagioli
  • 12,722
  • 5
  • 59
  • 57
  • Why would you prefer the `.origin` over `window.location` or `document.location`? That would break the OP's relative path ("../g"), as well as relative fragments or search strings. – ericP Sep 15 '21 at 07:07
  • @ericP I do not remember why, frankly, but you are right, `origin` would not suit the OP's case. Anyway by having a second look at the OP's question, it seems that the base parameter should come from the attribute `action` of a `form` DOM element, not from the current location (although later in his question the "I'm on" may suggests otherwise). Regarding the search strings, according to his question he is not interested in keeping them. I have edited my answer with a more pertinent snippet. – Luca Fagioli Sep 17 '21 at 07:07