Ostatnio musiałem się dobrać do części path URL po zwróconego przez ajax call. Problem polegał na tym, że część scheme, host, port mogły być różne i się zmieniać. To znaczy, port mógł istnieć lub nie, scheme mogła być różna zaś host mógł być wielokropkowy. Pewnie jakimiś hackami mógłbym się do tego dobrać rozsądnie. Ale po co?

Skoro można wykorzystać trick, stworzyć element a i przypisać do href url. Dzięki czemu mamy dostęp do wszystkich własności jakich potrzebujemy :)

Dla przykładu, wklejcie to w dev tools (ctrl+shift+i) i zobaczcie co się stanie:

var x = document.createElement('a');
x.href = 'http://www.contoso.com:2345/cos/tam/jeszcze?a=10'
console.dir({
  hash: x.hash,
  host: x.host,
  hostname: x.hostname,
  href: 'http://www.contoso.com/cos/tam/jeszcze?a=10',
  pathname: x.pathname,
  port: x.port,
  protocol: x.protocol,
  search: x.search,
  file: x.pathname.split('/').pop()
})

Dobre, i przyjemne :)

Jakbyście chcieli to wykorzystać w angular, to można to zamknąć w serwis, do tego dodając parsowanie query string do obiektu :)

(function (angular, document, undefined) {

    var app = angular.module('util.services', [ ]);

    app.factory('uri', function () {

        var element;

        function unserialize (query) {
            var params = {};
            // http://stevenbenner.com/2010/03/javascript-regex-trick-parse-a-query-string-into-an-object/
            query.replace(      new RegExp("([^?=&]+)(=([^&]*))?", "g"),      function($0, $1, $2, $3) { params[$1] = $3; }
            );

            return params;
        }

    return {
        parse: function (url) {

            if(!element) {
                element = document.createElement('a');
            }

            element.href = url;
            return {
                hash: element.hash,
                host: element.host,
                hostname: element.hostname,
                href: url,
                pathname: element.pathname,
                port: element.port,
                protocol: element.protocol,
                search: element.search,
                file: element.pathname.split('/').pop(),
                params: unserialize(element.search)
            }
        }
    };
});


})(window.angular, window.document);

5 KOMENTARZE

  1. dzieki, jak bede potrzebowal bardziej zaawansowanych parametrow query to pewnie z tego skorzystam. to co mnie bardziej intersowalo to `path` to, co akurat jest pominiete w tej bibliotece. Dostaje url: http://www/a/b/c i mnie intersuje /a/b/c. to query parsing dodalem by bylo na wszelki wypadek, ale chyba wywale bo nie potrzebne :)

    Ale patrzac na kod calego rozszerzenia, to naprwade zaczynam chyba rozumiec co mial Rob na mysli piszac _frameworkless_ javascript. tyle kodu tylko po to by modyfikowac query string, kiedy mozna w 4 linijkach to napisac i miec zglowy, potem wrazie co poprawiac.

  2. AA, rozumiem coś jak daj mi RouteValues w ASP.NET MVC

    Ale się nie zgodzę, że Rob to miał na myśli. Wskazywał właśnie na “prehistoryczne” czasy gdy wszystko robiło się pluginami jQuery jako wzór. Ten plugin ma banalne, ale sensowne API (nieważne czy implementacja ma sens) i jeśli przestanie mi odpowiadać to łatwo zastąpię go czymś innym. Kwintesencja podejścia: małe niezależne moduły (modulo zależność od jQuery). IMHO nie miał na myśli tego, żeby wszystko samemu robić. Akurat kwestia url.set(‘x’, ‘y’) nie jest taka trywialna jakby się mogło wydawać :)

  3. true, masz rację z tym podejściem :) ale z drugiej strony tez o to chodzilo, by nie zaciagac czegos poteznego do czegos malego.

    ale tak btw:

    “`
    var query = $.param({name: ‘val’, two: 5});
    “`

    i po klopocie ;) przynajmniej z pobieraniem query string z wykorzystaniem jquery, metoda jest [wbudowana](https://api.jquery.com/jQuery.param/).

  4. Ja potrzebowałem zmienić url (albo nadpisać, albo ustawić) a nie go parsować (to faktycznie w miarę proste). To było w aplikacji ASP.NET MVC, więc dane z routingu raczej bezpośrednio ustawiałem widżetom atrybutami data-* z poziomu razora.

Comments are closed.