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'

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];
}

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"

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


3

Prosty sposób jest następujący

public static String stripQueryStringAndHashFromPath(String uri) {
 return uri.replaceAll(("(\\?.*|\\#.*)"), "");
}

2

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

var newURL = testURL.match(new RegExp("[^?]+"))

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, "")
);

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', '');

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

@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.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.