【问题标题】:Remove querystring from URL从 URL 中删除查询字符串
【发布时间】:2011-02-02 05:09:10
【问题描述】:

在 Javascript 中从路径中删除查询字符串的简单方法是什么? 我见过一个使用 window.location.search 的 Jquery 插件。我不能这样做:在我的例子中,URL 是一个从 AJAX 设置的变量。

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

【问题讨论】:

    标签: javascript jquery


    【解决方案1】:

    一个简单的方法是:

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

    对于那些也希望删除哈希(不是原始问题的一部分)不存在查询字符串时的人,这需要更多:

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

    编辑

    @caub(最初是@crl)提出了一个更简单的组合,适用于查询字符串和哈希(尽管它使用 RegExp,以防有人对此有疑问):

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

    【讨论】:

    • +1... 实际上在这种情况下 split() 比 substring() 更好。
    • 边际优化如果重要(可能不重要):split('?', 1)[0].
    • @ChristianVielma:? 是字符串文字,而不是正则表达式。
    • @Robusto 对不起,我的错...我在 Java 中检查它(将其解释为正则表达式):(
    • 嘿,Robusto,为什么不.split(/[?#]/)[0]
    【解决方案2】:

    第二次更新:为了提供一个全面的答案,我正在对各种答案中提出的三种方法进行基准测试。

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

    在 Mac OS X 10.6.2 上的 Firefox 3.5.8 中的结果:

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

    在 Mac OS X 10.6.2 上的 Chrome 5.0.307.11 中的结果:

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

    请注意,substring 方法的功能较差,因为如果 URL 不包含查询字符串,它会返回一个空白字符串。如预期的那样,其他两种方法将返回完整的 URL。然而有趣的是 substring 方法是最快的,尤其是在 Firefox 中。


    第一次更新: 实际上 split() 方法suggested by Robusto 是比我之前建议的更好的解决方案,因为即使没有查询字符串它也可以工作:

    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"
    

    原答案:

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

    【讨论】:

    • O_O 确实很全面,但是……为什么?最灵活和最合适的方法显然会胜出,这里绝对不关心速度。
    • @deceze:只是出于好奇……因为在 Angus 的答案中,关于正则表达式方法的性能存在争议。
    • 非常有趣,丹尼尔。如果我必须在一个页面上进行 10K URL 解析,我将寻求另一项工作。 :)
    • 实际上我有点惊讶于可以在 44 毫秒内完成 10k 次正则表达式匹配。在未来,我想我会倾向于更多地使用它们。
    【解决方案3】:

    这可能是一个老问题,但我已经尝试过这种方法来删除查询参数。对我来说似乎工作顺利,因为我需要重新加载以及删除查询参数。

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

    另外,由于我使用的是简单的字符串加法操作,我猜性能会很好。但还是值得和this answer中的sn-ps比较

    【讨论】:

    • 最佳解决方案 IMO。是否有缺点或不起作用的情况?
    【解决方案4】:
    var path = "path/to/myfile.png?foo=bar#hash";
    
    console.log(
        path.replace(/(\?.*)|(#.*)/g, "")
    );
    

    【讨论】:

      【解决方案5】:

      我可以理解以前的痛苦,在现代你可以像下面这样超级容易地得到这个

      let url = new URL('https://example.com?foo=1&bar=2&foo=3');
      let params = new URLSearchParams(url.search);
      
      // Delete the foo parameter.
      params.delete('foo'); //Query string is now: 'bar=2'
      
      // now join the query param and host
      let newUrl =  url.origin + '/' + params.toString();
      

      【讨论】:

        【解决方案6】:

        一个简单的方法是你可以这样做

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

        【讨论】:

          【解决方案7】:

          使用标准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 当他所做的只是在之后返回路径名时,协议有什么关系?
          • @The Fool - new URL() 将失败,否则会出现“无效 URL”错误消息
          【解决方案8】:

          如果你喜欢 RegEx....

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

          【讨论】:

          • 正则表达式很慢 - 使用简单快速的方法。
          • @Angus:您的循环给您“脚本可能正忙...”,因为您忘记增加 a++;。修复测试,在 iMac 2.93Ghz Core 2 Duo 上的 Firefox 3.6 中,RegEx 为 8 毫秒,拆分方法为 3 毫秒……不过答案是 +1,因为它仍然是另一种选择。
          • 谢谢 - 我在几分钟前修好了! - 但关键是当您谈论 0.000005 秒时,即使是 reg exp 操作,性能对于任何解决方案都不是问题:-)
          • match() 返回一个对象。你可能不希望那样。致电toString()(或+'')。
          • 鲍勃 - 很好的收获。实际上它返回一个匹配数组——在这种情况下是一个字符串数组。所以 testURL.match(new RegExp("[^?]+"))[0] 做到了
          【解决方案9】:

          如果使用backbone.js(其中包含url anchor作为路由),可能会出现urlquery string

          1. url anchor之前:

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

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

          解决方案:

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

          【讨论】:

            【解决方案10】:

            var u = new URL('https://server.de/test?q#h')
            u.hash = ''
            u.search = ''
            console.log(u.toString())

            【讨论】:

            • 这是该线程中唯一有效的答案。
            【解决方案11】:

            如果需要对 URL 进行复杂的操作,可以查看jQuery url parser plugin

            【讨论】:

              【解决方案12】:
              (() => {
                      '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();
                      }
              })();
              

              我就是这样做的,也支持正则表达式。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2016-07-22
                • 2011-03-28
                • 1970-01-01
                • 2018-12-08
                • 2019-02-27
                • 2019-01-14
                相关资源
                最近更新 更多