【问题标题】:How can I get a specific parameter from location.search? [duplicate]如何从 location.search 获取特定参数? [复制]
【发布时间】:2010-10-06 02:44:24
【问题描述】:

如果我有一个 URL,例如

http://localhost/search.php?year=2008

我将如何编写一个 JavaScript 函数来获取变量 year 并查看它是否包含任何内容?

我知道可以使用 location.search 完成,但我不知道它是如何获取参数的。

【问题讨论】:

  • string yr = location.search.substring(6); alert(yr);
  • location.search.split("year=")[1] 仅在最简单的情况下
  • 看起来问题已经结束,但最新的答案不在这里:new URLSearchParams(location.search).get('year')
  • 您可以使用 URLSearchParams.getAll() 返回与特定参数关联的所有值:console.log(urlParams.getAll('size'));

标签: javascript url


【解决方案1】:

一种非正则表达式的方法,您可以简单地按字符 '&' 拆分并遍历键/值对:

function getParameter(paramName) {
  var searchString = window.location.search.substring(1),
      i, val, params = searchString.split("&");

  for (i=0;i<params.length;i++) {
    val = params[i].split("=");
    if (val[0] == paramName) {
      return val[1];
    }
  }
  return null;
}

2020 年编辑:

现在,在modern browsers,您可以使用URLSearchParams constructor

const params = new URLSearchParams('?year=2020&month=02&day=01')

// You can access specific parameters:
console.log(params.get('year'))
console.log(params.get('month'))

// And you can iterate over all parameters
for (const [key, value] of params) {
  console.log(`Key: ${key}, Value: ${value}`);
}

【讨论】:

  • val 不是一个全局变量吗?
  • 那我可以做 if(getParameter("year") != "") { var year=getParameter("year"); document.location.href=page.php?year=$year&etc 等
  • @sarmenhb:你可以这样做:var year=getParameter("year"); if (year){ document.location.href='page.php?year='+year;}
  • @Luca Matteis:不,val 不是全局变量。它被定义为 var searchString, i, val, ... 中的本地 var
  • 优雅易用!为什么没有将其标记为答案?
【解决方案2】:

这个问题很老了,而且在 JavaScript 中已经发生了变化。 您现在可以这样做了:

const params = {}
document.location.search.substr(1).split('&').forEach(pair => {
  [key, value] = pair.split('=')
  params[key] = value
})

你会得到包含2008params.year。 您还可以在 params 对象中获得其他查询参数。


编辑:一种更短/更简洁的方式:

const params = new Map(location.search.slice(1).split('&').map(kv => kv.split('=')))

然后您可以测试year 参数是否存在:

params.has('year')  // true

或者通过以下方式检索它:

params.get('year')  // 2008

编辑 2020

您可以将 URL 参数转换为对象:

const params = location.search.slice(1).split('&').reduce((acc, s) => {
  const [k, v] = s.split('=')
  return Object.assign(acc, {[k]: v})
}, {})

那么就可以当成一个普通的JS对象了:

params.year  // 2008

【讨论】:

  • 你应该使用 .reduce() 而不是 .forEach
  • 不适用于 .reduce()。只有第一个参数被写入 params 对象。签入 Chrome 开发工具。你能仔细检查一下,然后用 forEach() 代替吗?
  • @vinyll @tylik const getQueryObject = locationSearchString =&gt; locationSearchString .substr(1) .split('&amp;') .reduce((queryObject, keyValuePair) =&gt; { const [key, value] = keyValuePair.split('='); queryObject[key] = value; return queryObject; }, {});
  • 您应该使用 URL,但如果您打算这样做,则需要在用 & 和 = 分割后对每个键和值调用 decodeURIComponent。这就是如何在键和值本身以及像 # 这样的其他内容中对 = 和 & 进行编码,因为它们都将被编码。
【解决方案3】:

一个简单的单线解决方案:

let query = Object.assign.apply(null, location.search.slice(1).split('&').map(entry => ({ [entry.split('=')[0]]: entry.split('=')[1] })));

扩展和解释:

// define variable
let query;

// fetch source query
query = location.search;

// skip past the '?' delimiter
query = query.slice(1);

// split source query by entry delimiter
query = query.split('&');

// replace each query entry with an object containing the query entry
query = query.map((entry) => {

   // get query entry key
   let key = entry.split('=')[0];

   // get query entry value
   let value = entry.split('=')[1];

   // define query object
   let container = {};

   // add query entry to object
   container[key] = value;

   // return query object
   return container;
});

// merge all query objects
query = Object.assign.apply(null, query);

【讨论】:

    【解决方案4】:

    这是我喜欢做的事情:

    window.location.search
        .substr(1)
        .split('&')
        .reduce(
            function(accumulator, currentValue) {
                var pair = currentValue
                    .split('=')
                    .map(function(value) {
                        return decodeURIComponent(value);
                    });
    
                accumulator[pair[0]] = pair[1];
    
                return accumulator;
            },
            {}
        );
    

    当然,您可以使用现代语法或将所有内容写成一行来使其更紧凑...

    这个由你来决定。

    【讨论】:

      【解决方案5】:

      ES6 答案:

      const parseQueryString = (path = window.location.search) =>
        path.slice(1).split('&').reduce((car, cur) => {
         const [key, value] = cur.split('=')
         return { ...car, [key]: value } 
        }, {})
      

      例如:

      parseQueryString('?foo=bar&foobar=baz')
      // => {foo: "bar", foobar: "baz"}
      

      【讨论】:

        【解决方案6】:

        用一行从 location.search 中获取参数:

        const params = new Map(this.props.location.search.slice(1).split('&').map(param => param.split('=')))
        

        那么,简单地说:

        if(params.get("year")){
          //year exists. do something...
        } else {
          //year doesn't exist. do something else...
        }
        

        【讨论】:

          【解决方案7】:

          我最喜欢的获取 URL 参数的方法是:

          var parseQueryString = function() {
          
              var str = window.location.search;
              var objURL = {};
          
              str.replace(
                  new RegExp( "([^?=&]+)(=([^&]*))?", "g" ),
                  function( $0, $1, $2, $3 ){
                      objURL[ $1 ] = $3;
                  }
              );
              return objURL;
          };
          
          //Example how to use it: 
          var params = parseQueryString();
          alert(params["foo"]); 
          

          【讨论】:

          • 那个老人总是说“当你遇到一个只能用正则表达式解决的问题时,你实际上有两个问题”。
          • 我喜欢这个,很可爱!你捕获'='有什么原因吗?你可以说 /([^?=&]+)=([^&]*)/g 并且你的参数是 (match, key, value)?
          • location.search.split("year=")[1] 不是更简单吗?
          • @Rodrigo 如果你有多个参数,它会爆炸
          • 更优雅——没有正则表达式/更现代(2018)——解决方案在这里:stackoverflow.com/a/42316411/328117
          【解决方案8】:

          我在这个问题上玩了一下,最后我用了这个:

          function getJsonFromUrl() {
            return Object.assign(...location.search.substr(1).split("&").map(sliceProperty));
          }
          
          • Object.assign 将对象列表转换为一个对象
          • 扩展运算符... 将数组转换为列表
          • location.search.substr(1).split("&amp;") 获取所有参数作为属性数组 (foo=bar)
          • map 遍历每个属性并将它们拆分为一个数组(调用 splitPropertysliceProperty)。

          splitProperty:

            function splitProperty(pair) {
              [key, value] = pair.split("=")
              return { [key]: decodeURIComponent(value) }
            }
          
          • =拆分
          • 将数组解构为包含两个元素的数组
          • 使用动态属性语法返回一个新对象

          sliceProperty:

            function sliceProperty(pair) {
              const position = pair.indexOf("="),
                key = pair.slice(0, position),
                value = pair.slice(position + 1, pair.length);
              return { [key]: decodeURIComponent(value) }
            }
          
          • 设置=的位置、key和value
          • 使用动态属性语法返回一个新对象

          我认为splitProperty 更漂亮,但sliceProperty 更快。运行JsPerf了解更多信息。

          【讨论】:

            【解决方案9】:

            你可以使用window.URL类:

            new URL(location.href).searchParams.get('year')
            // Returns 2008 for href = "http://localhost/search.php?year=2008".
            // Or in two steps:
            const params = new URL(location.href).searchParams;
            const year = params.get('year');
            

            【讨论】:

            • window.URL 很方便,如果只使用最新的 Chrome 和 Firefox
            • 这应该是当今公认的答案
            • @pungggi ...直到您的客户使用 Internet Explorer :(
            • @haykam 然后使用 polyfill!
            【解决方案10】:

            最简单的方法是拥有

            if (document.location.search.indexOf('yourtext=') >= 0) {
                // your code
            } else {
                // what happens?
            }
            

            indexOf()

            indexOf(text) 函数返回

            • A Whole NUMBER BELOW 0,当函数中传递的文本不在您要查找的任何变量或字符串中时 - 在本例中为 document.location.search
            • 等于 0 或更高的整数,当函数中传递的文本位于您要查找的任何变量或字符串中时 - 在本例中为 document.location.search

            我希望这很有用,@gumbo

            【讨论】:

            • 这会失败,查询字符串如?notyourtext=foo
            • ...使用?yourtext=foo&amp;notyourtext=bar时失败。
            【解决方案11】:

            我使用了 Alex 的变体 - 但需要将多次出现的参数转换为数组。似乎有很多选择。我不想依赖另一个库来做这么简单的事情。我想这里发布的其他选项之一可能会更好 - 由于直截了当,我改编了 Alex 的。

            parseQueryString = function() {
                var str = window.location.search;
                var objURL = {};
            
                // local isArray - defer to underscore, as we are already using the lib
                var isArray = _.isArray
            
                str.replace(
                    new RegExp( "([^?=&]+)(=([^&]*))?", "g" ),
                    function( $0, $1, $2, $3 ){
            
                        if(objURL[ $1 ] && !isArray(objURL[ $1 ])){
                            // if there parameter occurs more than once, convert to an array on 2nd
                            var first = objURL[ $1 ]
                            objURL[ $1 ] = [first, $3]
                        } else if(objURL[ $1 ] && isArray(objURL[ $1 ])){
                            // if there parameter occurs more than once, add to array after 2nd
                            objURL[ $1 ].push($3)
                        }
                        else
                        {
                            // this is the first instance
                            objURL[ $1 ] = $3;
                        }
            
                    }
                );
                return objURL;
            };
            

            【讨论】:

            • 如果一个参数出现不止一次,它应该只被视为一个数组,如果它以[] 结尾(例如foo[]=1&amp;foo[]=2)。否则,您应该使用第一次或最后一次出现。
            【解决方案12】:
            function gup( name ) {
                name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
                var regexS = "[\\?&]"+name+"=([^&#]*)";
                var regex = new RegExp( regexS );
                var results = regex.exec( window.location.href );
                if( results == null )
                    return "";
                else
                    return results[1];
            }
            var year = gup("year"); // returns "2008"
            

            【讨论】:

            • 您应该使用window.location.search 而不是window.location.href。这将简化您的表达式,而不必检查哈希或查询标记
            • 在创建正则表达式之前,转义“名称”中的所有正则表达式元字符是个好主意。
            【解决方案13】:

            我花了一段时间才找到这个问题的答案。大多数人似乎都在建议正则表达式解决方案。我非常喜欢使用经过尝试和测试的代码,而不是我或其他人即时想到的正则表达式。

            我使用此处提供的 parseUri 库: http://stevenlevithan.com/demo/parseuri/js/

            它可以让你完全按照你的要求去做:

            var uri = 'http://localhost/search.php?year=2008';
            var year = uri.queryKey['year'];
            // year = '2008'
            

            【讨论】:

            • var year = parseUri(window.location.search).queryKey['year'];是一个更相关的例子。上面的那个不适用于 parseUri 脚本的 1.2 版。
            【解决方案14】:

            以下使用正则表达式并仅搜索 URL 的查询字符串部分。

            最重要的是,此方法支持普通和数组参数,如 http://localhost/?fiz=zip&amp;foo[]=!!=&amp;bar=7890#hashhashhash

            function getQueryParam(param) {
                var result =  window.location.search.match(
                    new RegExp("(\\?|&)" + param + "(\\[\\])?=([^&]*)")
                );
            
                return result ? result[3] : false;
            }
            
            console.log(getQueryParam("fiz"));
            console.log(getQueryParam("foo"));
            console.log(getQueryParam("bar"));
            console.log(getQueryParam("zxcv"));
            

            输出:

            zip
            !!=
            7890
            false
            

            【讨论】:

              猜你喜欢
              • 2021-08-16
              • 2012-09-17
              • 2016-07-15
              • 1970-01-01
              • 2013-10-22
              • 1970-01-01
              • 2018-07-23
              • 2021-08-10
              相关资源
              最近更新 更多