Eliminar la cadena de consulta de la URL

144

¿Cuál es una manera fácil de eliminar la cadena de consulta de una ruta en Javascript? He visto un complemento para Jquery que usa window.location.search. No puedo hacer eso: la URL en mi caso es una variable que se establece desde AJAX.

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

Respuestas:

346

Una manera fácil de conseguir esto es:

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

Para aquellos que también desean eliminar el hash (que no forma parte de la pregunta original) cuando no existe una cadena de consulta , eso requiere un poco más:

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

EDITAR

@caub (originalmente @crl) sugirió un combo más simple que funciona tanto para la cadena de consulta como para el hash (aunque usa RegExp, en caso de que alguien tenga un problema con eso):

function getPathFromUrl(url) {
  return url.split(/[?#]/)[0];
}
Robusto
fuente
44
+1 ... En realidad, split () es mejor que substring () en este caso.
Daniel Vassallo
10
Optimización marginal si importa (probablemente no): split('?', 1)[0].
bobince
@ChristianVielma: este ?es un literal de cadena, no una expresión regular.
Robusto
@Robusto Lo siento, mi mal ... Lo estaba comprobando en Java (que lo interpreta como una expresión regular) :(
Christian Vielma
44
Hola Robusto, ¿y por qué no .split(/[?#]/)[0]?
caub
32

Segunda actualización: en un intento de proporcionar una respuesta integral, estoy comparando los tres métodos propuestos en las diferentes respuestas.

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 en Firefox 3.5.8 en Mac OS X 10.6.2:

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

Resultados en Chrome 5.0.307.11 en Mac OS X 10.6.2:

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

Tenga en cuenta que el método de subcadena tiene una funcionalidad inferior, ya que devuelve una cadena en blanco si la URL no contiene una cadena de consulta. Los otros dos métodos devolverían la URL completa, como se esperaba. Sin embargo, es interesante notar que el método de subcadena es el más rápido, especialmente en Firefox.


1ª ACTUALIZACIÓN: en realidad, el método split () sugerido por Robusto es una mejor solución que la que sugerí anteriormente, ya que funcionará incluso cuando no haya una cadena 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"

Respuesta original

var testURL = '/Products/List?SortDirection=dsc&Sort=price&Page=3&Page2=3';
testURL.substring(0, testURL.indexOf('?'));    // Returns: "/Products/List"
Daniel Vassallo
fuente
10
O_O Muy completo de hecho, pero ... ¿por qué? El método más flexible y apropiado obviamente gana, la velocidad no tiene ninguna importancia aquí.
deceze
1
@deceze: Solo por curiosidad ... Y porque hubo una discusión sobre el rendimiento del método regex en los comentarios de la respuesta de Angus.
Daniel Vassallo
66
Muy interesante, Daniel. Y si alguna vez tengo que hacer análisis de URL de 10K en una página, buscaré otra línea de trabajo. :)
Robusto
De hecho, estoy un poco sorprendido de que se puedan hacer 10k partidos de expresiones regulares en 44 ms. En el futuro, creo que me inclinaré a usarlos más.
TheGerm
12

Esta puede ser una pregunta antigua, pero he intentado este método para eliminar los parámetros de consulta. Parece funcionar sin problemas para mí, ya que también necesitaba una recarga combinada con la eliminación de los parámetros de consulta.

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

Además, como estoy usando una operación simple de adición de cadenas, supongo que el rendimiento será bueno. Pero aún así vale la pena comparar con fragmentos en esta respuesta

damitj07
fuente
3

Una manera simple es que puedes hacer lo siguiente

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

Si te gusta RegEx ...

var newURL = testURL.match(new RegExp("[^?]+"))
empollón
fuente
1
el regexp es lento, vaya con la forma fácil y rápida.
Aristos
1
@Angus: Tu ciclo te está dando "Un script puede estar ocupado ..." porque olvidaste incrementarlo a++;. Arreglando las pruebas, en mi Firefox 3.6 en un iMac 2.93Ghz Core 2 Duo, obtengo 8 ms para el RegEx y 3 ms para el método de división ... Sin embargo, +1 para la respuesta, porque todavía es otra opción.
Daniel Vassallo
1
gracias - lo arreglé hace unos minutos! - pero el punto es cuando estás hablando 0.000005 segundos incluso para la operación de exp exp, el rendimiento no es un problema para ninguna solución :-)
plodder
1
match()devuelve un objeto Probablemente no quieras eso. Llamarlo toString()(o +'').
bobince
1
Bob, buena captura. En realidad, devuelve una serie de coincidencias, una matriz de cadenas en este caso. Entonces testURL.match (nuevo RegExp ("[^?] +")) [0] lo hace
plodder
2
var path = "path/to/myfile.png?foo=bar#hash";

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

Si usa backbone.js (que contiene url anchorcomo ruta), query stringpuede aparecer la url :

  1. antes url anchor:

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

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

Solución:

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

Un enfoque que usa el estándar 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
fuente
@Brad, ¿qué importa el protocolo cuando todo lo que hace es devolver el nombre de ruta despué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();
        }
})();

Así lo hice, también tiene soporte RegEx.

javascript-noob
fuente