Remova a string de consulta do URL

144

Qual é uma maneira fácil de remover a string de consulta de um caminho em Javascript? Eu vi um plugin para Jquery que usa window.location.search. Não posso fazer isso: o URL no meu caso é uma variável definida no AJAX.

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

Respostas:

346

Uma maneira fácil de conseguir isso é:

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

Para aqueles que também desejam remover o hash (não faz parte da pergunta original) quando não existe nenhuma string de consulta , isso requer um pouco mais:

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

EDITAR

@caub (originalmente @crl) sugeriu uma combinação mais simples que funciona tanto para a string de consulta quanto para o hash (embora use RegExp, caso alguém tenha um problema com isso):

function getPathFromUrl(url) {
  return url.split(/[?#]/)[0];
}
Robusto
fonte
4
+1 ... Atualmente, split () é melhor que substring () neste caso.
Daniel Vassallo 29/03
10
Otimização Marginal se importa (provavelmente não): split('?', 1)[0].
bobince
@ChristianVielma: Esta ?é uma string literal, não uma expressão regular.
precisa
@Robusto Sinto muito, meu mal ... Eu estava verificando em Java (que interpreta isso como um regex) :(
Christian Vielma
4
Hey Robusto, e por que não .split(/[?#]/)[0]?
caub 28/03
32

2ª Atualização: Na tentativa de fornecer uma resposta abrangente, estou comparando os três métodos propostos nas várias respostas.

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

Resultados no Firefox 3.5.8 no Mac OS X 10.6.2:

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

Resultados no Chrome 5.0.307.11 no Mac OS X 10.6.2:

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

Observe que o método de substring é inferior em funcionalidade, pois retorna uma string em branco se o URL não contiver uma string de consulta. Os outros dois métodos retornariam o URL completo, conforme o esperado. No entanto, é interessante notar que o método de substring é o mais rápido, especialmente no Firefox.


1ª ATUALIZAÇÃO: Na verdade, o método split () sugerido por Robusto é uma solução melhor que a sugerida anteriormente, pois funcionará mesmo quando não houver string de consulta:

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"

Resposta original:

var testURL = '/Products/List?SortDirection=dsc&Sort=price&Page=3&Page2=3';
testURL.substring(0, testURL.indexOf('?'));    // Returns: "/Products/List"
Daniel Vassallo
fonte
10
O_O Muito abrangente, mas ... por quê? O método mais flexível e apropriado obviamente vence, a velocidade não é de nenhuma preocupação aqui.
deceze
1
@ deceze: Só por curiosidade ... E porque houve uma discussão sobre o desempenho do método regex nos comentários da resposta de Angus.
precisa
6
Muito interessante, Daniel. E se eu tiver que analisar 10K em uma página, procurarei outra linha de trabalho. :)
Robusto
Na verdade, estou um pouco impressionado com o fato de podermos fazer 10k partidas de regex em 44ms. No futuro, acho que terei mais vontade de usá-los.
TheGerm 17/09/12
12

Esta pode ser uma pergunta antiga, mas tentei este método para remover parâmetros de consulta. Parece funcionar sem problemas para mim, pois eu precisava de uma atualização também combinada com a remoção de parâmetros de consulta.

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

Além disso, como estou usando uma operação simples de adição de cadeias, acho que o desempenho será bom. Ainda vale a pena comparar com trechos nesta resposta

damitj07
fonte
3

Uma maneira simples é fazer o seguinte

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

Se você gosta de RegEx ....

var newURL = testURL.match(new RegExp("[^?]+"))
plodder
fonte
1
o regexp é lento - siga o caminho mais fácil e rápido.
Aristos
1
@ Angus: Seu loop está fornecendo "Um script pode estar ocupado ..." porque você esqueceu de incrementar a++;. Corrigindo os testes, no meu Firefox 3.6 em um iMac 2.93Ghz Core 2 Duo, recebo 8ms para o RegEx e 3ms para o método split ... No entanto, +1 para a resposta, porque ainda é outra opção.
Daniel Vassallo 29/03
1
obrigado - eu consertei alguns minutos atrás! - mas o ponto é quando você está falando 0,000005 segundos, mesmo para a operação reg exp, o desempenho não é um problema para qualquer solução :-)
plodder
1
match()retorna um objeto. Você provavelmente não quer isso. Ligue toString()para ele (ou +'').
bobince
1
Bob - boa captura. Na verdade, ele retorna uma matriz de correspondências - uma matriz de seqüências de caracteres nesse caso. Então testURL.match (new RegExp ("[^?] +")) [0] faz isso
plodder
2
var path = "path/to/myfile.png?foo=bar#hash";

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

Se você usar o backbone.js (que contém url anchorcomo rota), o URL query stringpoderá aparecer:

  1. antes url anchor:

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

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

Solução:

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

Uma abordagem usando o padrão 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
fonte
@ Brad, o que o protocolo importa quando tudo o que ele faz é retornar o nome do caminho depois?
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();
        }
})();

Foi assim que fiz, também tem suporte para RegEx.

javascript-noob
fonte