Usuń querystring z adresu URL

145

Jaki jest łatwy sposób na usunięcie kwerendy ze ścieżki w JavaScript? Widziałem wtyczkę dla Jquery, która używa window.location.search. Nie mogę tego zrobić: adres URL w moim przypadku to zmienna ustawiana z AJAX.

var testURL = '/Products/List?SortDirection=dsc&Sort=price&Page=3&Page2=3&SortOrder=dsc'
Mathias F.
źródło

Odpowiedzi:

347

Prostym sposobem na to jest:

function getPathFromUrl(url) {
  return url.split("?")[0];
}

Dla tych, którzy chcą również usunąć hash (nie jest to część pierwotnego pytania), gdy nie ma zapytania , to wymaga trochę więcej:

function stripQueryStringAndHashFromPath(url) {
  return url.split("?")[0].split("#")[0];
}

EDYTOWAĆ

@caub (pierwotnie @crl) zasugerował prostszą kombinację, która działa zarówno dla ciągu zapytania, jak i skrótu (chociaż używa RegExp, na wypadek, gdyby ktoś miał z tym problem):

function getPathFromUrl(url) {
  return url.split(/[?#]/)[0];
}
Robusto
źródło
4
+1 ... Właściwie split () jest w tym przypadku lepszy niż substring ().
Daniel Vassallo
10
Marginalny optymalizacji jeżeli ma to znaczenie (pewnie nie) split('?', 1)[0].
bobince
@ChristianVielma: To ?jest ciąg znaków, a nie wyrażenie regularne.
Robusto
@Robusto Przepraszam, mój błąd ... Sprawdzałem to w Javie (co interpretuje to jako wyrażenie regularne) :(
Christian Vielma,
4
Hej Robusto, a dlaczego nie .split(/[?#]/)[0]?
caub
32

Druga aktualizacja: próbując udzielić wyczerpującej odpowiedzi, porównuję trzy metody zaproponowane w różnych odpowiedziach.

var testURL = '/Products/List?SortDirection=dsc&Sort=price&Page=3&Page2=3';
var i;

// Testing the substring method
i = 0;
console.time('10k substring');
while (i < 10000) {
    testURL.substring(0, testURL.indexOf('?'));
    i++;
}
console.timeEnd('10k substring');

// Testing the split method
i = 0;
console.time('10k split');
while (i < 10000) {
    testURL.split('?')[0]; 
    i++;
}
console.timeEnd('10k split');

// Testing the RegEx method
i = 0;
var re = new RegExp("[^?]+");
console.time('10k regex');
while (i < 10000) {
    testURL.match(re)[0]; 
    i++;
}
console.timeEnd('10k regex');

Wyniki w przeglądarce Firefox 3.5.8 w systemie Mac OS X 10.6.2:

10k substring:  16ms
10k split:      25ms
10k regex:      44ms

Wyniki w Chrome 5.0.307.11 w systemie Mac OS X 10.6.2:

10k substring:  14ms
10k split:      20ms
10k regex:      15ms

Zwróć uwagę, że metoda podciągów ma gorszą funkcjonalność, ponieważ zwraca pusty ciąg, jeśli adres URL nie zawiera zapytania. Pozostałe dwie metody zwróciłyby pełny adres URL, zgodnie z oczekiwaniami. Warto jednak zauważyć, że metoda podciągów jest najszybsza, szczególnie w przeglądarce Firefox.


1. AKTUALIZACJA: Właściwie metoda split () sugerowana przez Robusto jest lepszym rozwiązaniem niż to, które zasugerowałem wcześniej, ponieważ będzie działać nawet wtedy, gdy nie ma zapytania:

var testURL = '/Products/List?SortDirection=dsc&Sort=price&Page=3&Page2=3';
testURL.split('?')[0];    // Returns: "/Products/List"

var testURL2 = '/Products/List';
testURL2.split('?')[0];    // Returns: "/Products/List"

Oryginalna odpowiedź:

var testURL = '/Products/List?SortDirection=dsc&Sort=price&Page=3&Page2=3';
testURL.substring(0, testURL.indexOf('?'));    // Returns: "/Products/List"
Daniel Vassallo
źródło
10
O_O Rzeczywiście bardzo obszerne, ale… dlaczego? Najbardziej elastyczna i odpowiednia metoda oczywiście wygrywa, szybkość nie ma tu absolutnie żadnego znaczenia.
deceze
1
@deceze: Tylko z ciekawości ... A ponieważ w komentarzach do odpowiedzi Angusa był spór o działanie metody regex.
Daniel Vassallo
6
Bardzo interesujące, Daniel. A jeśli kiedykolwiek będę musiał przeprowadzić analizę adresów URL 10K na stronie, zamierzam poszukać innej pracy. :)
Robusto
Właściwie jestem trochę zdumiony, że można wykonać 10 000 dopasowań regex w 44 ms. Myślę, że w przyszłości będę skłonny używać ich częściej.
TheGerm
12

To może być stare pytanie, ale próbowałem tej metody, aby usunąć parametry zapytania. Wydaje się, że działa to bezproblemowo, ponieważ potrzebowałem również przeładowania połączonego z usunięciem parametrów zapytania.

window.location.href = window.location.origin + window.location.pathname;

Ponieważ używam prostej operacji dodawania ciągów, sądzę, że wydajność będzie dobra. Ale nadal warto porównać ze fragmentami w tej odpowiedzi

damitj07
źródło
3

Prosty sposób jest następujący

public static String stripQueryStringAndHashFromPath(String uri) {
 return uri.replaceAll(("(\\?.*|\\#.*)"), "");
}
karthik m
źródło
2

Jeśli interesujesz się wyrażeniami regularnymi ...

var newURL = testURL.match(new RegExp("[^?]+"))
kujon
źródło
1
wyrażenie regularne jest wolne - idź w łatwy i szybki sposób.
Aristos
1
@Angus: Twoja pętla wyświetla komunikat „Skrypt może być zajęty ...”, ponieważ zapomniałeś zwiększyć a++;. Naprawiając testy, w moim Firefoksie 3.6 na iMacu 2,93Ghz Core 2 Duo, otrzymuję 8ms dla RegEx i 3ms dla metody split ... Niemniej jednak +1 za odpowiedź, bo to jeszcze inna opcja.
Daniel Vassallo
1
dzięki - naprawiłem to kilka minut temu! - ale chodzi o to, że kiedy mówisz 0,000005 sekund nawet dla operacji reg exp, wydajność nie jest problemem dla żadnego rozwiązania :-)
plodder
1
match()zwraca obiekt. Prawdopodobnie tego nie chcesz. Wezwij toString()to (lub +'').
bobince
1
Bob - dobry chwyt. W rzeczywistości zwraca tablicę dopasowań - w tym przypadku tablicę ciągów. A więc testURL.match (new RegExp ("[^?] +")) [0] robi to
plodder
2
var path = "path/to/myfile.png?foo=bar#hash";

console.log(
    path.replace(/(\?.*)|(#.*)/g, "")
);
yckart
źródło
2

Jeśli używasz pliku backbone.js (który zawiera url anchorjako trasę), query stringmoże pojawić się adres URL :

  1. przed url anchor:

    var url = 'http://example.com?a=1&b=3#routepath/subpath';
  2. po url anchor:

    var url = 'http://example.com#routepath/subpath?a=1&b=3';

Rozwiązanie:

window.location.href.replace(window.location.search, '');
// run as: 'http://example.com#routepath/subpath?a=1&b=3'.replace('?a=1&b=3', '');
Vikyd
źródło
1

Podejście wykorzystujące standard URL:

/**
 * @param {string} path - A path starting with "/"
 * @return {string}
 */
function getPathname(path) {
  return new URL(`http://_${path}`).pathname
}

getPathname('/foo/bar?cat=5') // /foo/bar
golopot
źródło
@Brad jakie znaczenie ma protokół, kiedy wszystko, co robi, to potem zwraca ścieżkę?
The Fool
-3
(() => {
        'use strict';
        const needle = 'SortOrder|Page'; // example
        if ( needle === '' || needle === '{{1}}' ) { 
            return; 
        }           
        const needles = needle.split(/\s*\|\s*/);
        const querystripper = ev => {
                    if (ev) { window.removeEventListener(ev.type, querystripper, true);}
                    try {
                          const url = new URL(location.href);
                          const params = new URLSearchParams(url.search.slice(1));
                          for (const needleremover of needles) {
                                if (params.has(needleremover)) {
                                url.searchParams.delete(needleremover);
                                    window.location.href = url;
                            }
                          }     
                    } catch (ex) { }
        };          
        if (document.readyState === 'loading') {
                 window.addEventListener('DOMContentLoaded', querystripper, true);
        } else {
                 querystripper();
        }
})();

Tak to zrobiłem, ma też obsługę RegEx.

javascript-noob
źródło