Supprimer la chaîne de requête de l'URL

145

Quel est le moyen simple de supprimer la chaîne de requête d'un chemin en Javascript? J'ai vu un plugin pour Jquery qui utilise window.location.search. Je ne peux pas faire cela: l'URL dans mon cas est une variable définie à partir d'AJAX.

var testURL = '/Products/List?SortDirection=dsc&Sort=price&Page=3&Page2=3&SortOrder=dsc'
Mathias F
la source

Réponses:

347

Un moyen simple d'y parvenir est:

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

Pour ceux qui souhaitent également supprimer le hachage (ne faisant pas partie de la question d'origine) lorsqu'aucune chaîne de requête n'existe , cela nécessite un peu plus:

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

ÉDITER

@caub (à l'origine @crl) a suggéré un combo plus simple qui fonctionne à la fois pour la chaîne de requête et le hachage (bien qu'il utilise RegExp, au cas où quelqu'un aurait un problème avec cela):

function getPathFromUrl(url) {
  return url.split(/[?#]/)[0];
}
Robusto
la source
4
+1 ... En fait, split () est meilleur que substring () dans ce cas.
Daniel Vassallo
10
Optimisation marginale si elle compte (probablement pas): split('?', 1)[0].
bobince
@ChristianVielma: Ceci ?est une chaîne littérale, pas une expression régulière.
Robusto
@Robusto Je suis désolé, mon mauvais ... Je le vérifiais en Java (qui l'interprète comme une regex) :(
Christian Vielma
4
Hey Robusto, et pourquoi pas .split(/[?#]/)[0]?
caub
32

2e mise à jour: Pour tenter de fournir une réponse complète, je compare les trois méthodes proposées dans les différentes réponses.

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

Résultats dans Firefox 3.5.8 sur Mac OS X 10.6.2:

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

Résultats dans Chrome 5.0.307.11 sur Mac OS X 10.6.2:

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

Notez que la méthode de sous-chaîne est inférieure en fonctionnalité car elle renvoie une chaîne vide si l'URL ne contient pas de chaîne de requête. Les deux autres méthodes renverraient l'URL complète, comme prévu. Cependant, il est intéressant de noter que la méthode des sous-chaînes est la plus rapide, en particulier dans Firefox.


1ère MISE À JOUR: En fait, la méthode split () suggérée par Robusto est une meilleure solution que celle que j'ai suggérée plus tôt, car elle fonctionnera même s'il n'y a pas de chaîne de requête:

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"

Réponse originale:

var testURL = '/Products/List?SortDirection=dsc&Sort=price&Page=3&Page2=3';
testURL.substring(0, testURL.indexOf('?'));    // Returns: "/Products/List"
Daniel Vassallo
la source
10
O_O Très complet en effet, mais… pourquoi? La méthode la plus flexible et la plus appropriée l'emporte évidemment, la vitesse n'est absolument pas un problème ici.
deceze
1
@deceze: Juste pour la curiosité ... Et parce qu'il y avait un argument sur les performances de la méthode regex dans les commentaires de la réponse d'Angus.
Daniel Vassallo
6
Très intéressant, Daniel. Et si jamais je dois faire des analyses d'URL 10K sur une page, je vais chercher une autre ligne de travail. :)
Robusto
Je suis en fait un peu époustouflé de pouvoir faire des matchs regex 10k en 44ms. À l'avenir, je pense que je serai enclin à les utiliser davantage.
TheGerm
12

Cela peut être une vieille question, mais j'ai essayé cette méthode pour supprimer les paramètres de requête. Cela semble fonctionner correctement pour moi car j'avais besoin d'un rechargement combiné avec la suppression des paramètres de requête.

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

De plus, puisque j'utilise une simple opération d'addition de chaînes, je suppose que les performances seront bonnes. Mais il vaut toujours la peine de comparer avec des extraits de cette réponse

damitj07
la source
3

Un moyen simple est que vous pouvez faire comme suit

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

Si vous aimez RegEx ...

var newURL = testURL.match(new RegExp("[^?]+"))
bûcheur
la source
1
l'expression rationnelle est lente - allez-y avec le moyen le plus simple et rapide.
Aristos
1
@Angus: Votre boucle vous indique "Un script est peut-être occupé ..." parce que vous avez oublié d'incrémenter a++;. Correction des tests, dans mon Firefox 3.6 sur un iMac 2.93Ghz Core 2 Duo, j'obtiens 8ms pour le RegEx, et 3ms pour la méthode split ... Néanmoins +1 pour la réponse, car c'est encore une autre option.
Daniel Vassallo
1
merci - je l'ai réparé il y a quelques minutes! - mais le fait est que lorsque vous parlez de 0,000005 secondes même pour l'opération reg exp, les performances ne sont pas un problème pour aucune solution :-)
plodder
1
match()renvoie un objet. Vous ne voulez probablement pas ça. Appelez- toString()le (ou +'').
bobince
1
Bob - bonne prise. En fait, il renvoie un tableau de correspondances - un tableau de chaînes dans ce cas. Donc testURL.match (new RegExp ("[^?] +")) [0] le fait
plodder
2
var path = "path/to/myfile.png?foo=bar#hash";

console.log(
    path.replace(/(\?.*)|(#.*)/g, "")
);
yckart
la source
2

Si vous utilisez backbone.js (qui contient url anchorcomme route), l'url query stringpeut apparaître:

  1. avant url anchor:

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

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

Solution:

window.location.href.replace(window.location.search, '');
// run as: 'http://example.com#routepath/subpath?a=1&b=3'.replace('?a=1&b=3', '');
Vikyd
la source
1

Une approche utilisant la norme 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
la source
@Brad qu'importe le protocole quand il ne fait que renvoyer le chemin d'accès après?
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();
        }
})();

C'est comme ça que je l'ai fait, avec le support RegEx.

javascript-noob
la source