javascript读取queryString

概述

前端开发中,偶尔需要读取url中传递的参数,以前的方法是获取query string,然后通过正则表达式匹配。不过在ES6以后可以通过URLSearchParams接口,便捷操作了。
URL参数(也称为查询字符串参数或URL变量)用于通过URL从页面到页面或从客户端到服务器发送少量数据。它们可以包含各种有用的信息,例如搜索查询,链接引用,产品信息,用户首选项等。
在本文中,我们将向您展示如何使用JavaScript解析和操作URL参数。

获取URL参数

在现代浏览器中,这要归功于URLSearchParams接口,这变得容易得多。这定义了许多实用程序方法来使用URL的查询字符串。
假设我们的URL是:

https://example.com/?product=shirt&color=blue&newuser&size=m

我们可以使用window.location.search以下命令获取查询字符串:

const queryString = window.location.search;
console.log(queryString);
// ?product=shirt&color=blue&newuser&size=m

然后,我们可以使用解析查询字符串的参数URLSearchParams

const urlParams = new URLSearchParams(queryString);

然后,我们对结果调用其任何方法。
例如,URLSearchParams.get()将返回与给定搜索参数关联的第一个值:

const product = urlParams.get('product')
console.log(product);
// shirt
const color = urlParams.get('color')
console.log(color);
// blue
const newUser = urlParams.get('newuser')
console.log(newUser);
// empty string

其他有用的方法

检查参数是否存在

您可以URLSearchParams.has()用来检查某个参数是否存在:

console.log(urlParams.has('product'));
// true
console.log(urlParams.has('paymentmethod'));
// false

您可以URLSearchParams.getAll()用来返回与特定参数关联的所有值:

console.log(urlParams.getAll('size'));
// [ 'm' ]
//Programmatically add a second size parameter.
urlParams.append('size', 'xl');
console.log(urlParams.getAll('size'));
// [ 'm', 'xl' ]

遍历参数

URLSearchParams还提供了一些熟悉的Object迭代器方法,使您可以迭代其键,值和条目:

const
  keys = urlParams.keys(),
  values = urlParams.values(),
  entries = urlParams.entries();
for (const key of keys) console.log(key);
// product, color, newuser, size
for (const value of values) console.log(value);
// shirt, blue, , m
for(const entry of entries) {
  console.log(`${entry[0]}: ${entry[1]}`);
}
// product: shirt
// color: blue
// newuser:
// size: m

浏览器支持

浏览器对的支持URLSearchParams很好。在撰写本文时,所有主流浏览器均支持该功能。
如果您必须支持Internet Explorer等旧版浏览器,则可以使用polyfill。或者,您可以继续阅读本教程的其余部分,并学习如何进行自己的学习。
滚动您自己的查询字符串解析功能
让我们继续使用上一节中使用的URL:
http://example.com/?product=shirt&color=blue&newuser&size=m
这是一个为所有URL参数提供一个整洁对象的函数:

function getAllUrlParams(url) {
  // get query string from url (optional) or window
  var queryString = url ? url.split('?')[1] : window.location.search.slice(1);
  // we'll store the parameters here
  var obj = {};
  // if query string exists
  if (queryString) {
    // stuff after # is not part of query string, so get rid of it
    queryString = queryString.split('#')[0];
    // split our query string into its component parts
    var arr = queryString.split('&');
    for (var i = 0; i < arr.length; i++) {
      // separate the keys and the values
      var a = arr[i].split('=');
      // set parameter name and value (use 'true' if empty)
      var paramName = a[0];
      var paramValue = typeof (a[1]) === 'undefined' ? true : a[1];
      // (optional) keep case consistent
      paramName = paramName.toLowerCase();
      if (typeof paramValue === 'string') paramValue = paramValue.toLowerCase();
      // if the paramName ends with square brackets, e.g. colors[] or colors[2]
      if (paramName.match(/\[(\d+)?\]$/)) {
        // create key if it doesn't exist
        var key = paramName.replace(/\[(\d+)?\]/, '');
        if (!obj[key]) obj[key] = [];
        // if it's an indexed array e.g. colors[2]
        if (paramName.match(/\[\d+\]$/)) {
          // get the index value and add the entry at the appropriate position
          var index = /\[(\d+)\]/.exec(paramName)[1];
          obj[key][index] = paramValue;
        } else {
          // otherwise add the value to the end of the array
          obj[key].push(paramValue);
        }
      } else {
        // we're dealing with a string
        if (!obj[paramName]) {
          // if it doesn't exist, create property
          obj[paramName] = paramValue;
        } else if (obj[paramName] && typeof obj[paramName] === 'string'){
          // if property does exist and it's a string, convert it to an array
          obj[paramName] = [obj[paramName]];
          obj[paramName].push(paramValue);
        } else {
          // otherwise add the property
          obj[paramName].push(paramValue);
        }
      }
    }
  }
  return obj;
}

您将很快看到它的工作原理,但是首先,这里是一些用法示例:

getAllUrlParams().product; // 'shirt'
getAllUrlParams().color; // 'blue'
getAllUrlParams().newuser; // true
getAllUrlParams().nonexistent; // undefined
getAllUrlParams('http://test.com/?a=abc').a; // 'abc'

这是一个演示供您试用。

使用此函数前的注意事项

我们的功能假定参数用&字符分隔,如 W3C规范 中所示。但是,通常没有明确定义 URL参数格式,因此您有时可能会看到;或将其&作为分隔符
如果参数没有等号或参数有等号但没有值,则我们的函数仍然有效。
重复参数的值放入数组中。
如果您只想要一个函数,可以将其放入代码中,那么现在就完成了。如果您想了解该功能的工作原理,请继续阅读。
以下部分假定您了解一些JavaScript,包括函数,对象和数组。如果您需要复习,请查看 MDN JavaScript参考

函数如何运作

总体而言,该功能需要一个URL的查询字符串(后部分?和前#)和吐出来的是数据在一个整洁的对象。
首先,此行说,如果我们指定了URL,则在问号后获取所有内容,否则,只需使用窗口的URL:

var queryString = url ? url.split('?')[1] : window.location.search.slice(1);

接下来,我们将创建一个对象来存储我们的参数:

var obj = {};

如果查询字符串存在,我们将开始对其进行解析。首先,我们必须确保从删除所有部分#,因为它不是查询字符串的一部分:

queryString = queryString.split('#')[0];

现在,我们可以将查询字符串分成其组成部分:

var arr = queryString.split('&');

这将为我们提供如下所示的数组:

['product=shirt', 'color=blue', 'newuser', 'size=m']

接下来,我们将遍历此数组,并将每个项目分为一个键和一个值,我们将很快将它们放入对象中:

var a = arr[i].split('=');

让我们为各个变量分配键和值。如果没有参数值,我们将其设置true为表示参数名称存在。可以根据您的用例随意更改:

var paramName = a[0];
var paramValue = typeof (a[1]) === 'undefined' ? true : a[1];

(可选)您可以将所有参数名称和值设置为小写。这样,您可以避免有人使用example=TRUE而不是将流量发送到URL example=true且脚本中断的情况。(我已经看到了这种情况。)但是,如果您的查询字符串需要区分大小写,请随时忽略此部分:

paramName = paramName.toLowerCase();
if (typeof paramValue === 'string') paramValue = paramValue.toLowerCase();

接下来,我们需要处理可以在中接收的各种类型的输入paramName。这可以是索引数组,非索引数组或常规字符串。
如果它是一个索引数组,我们希望对应paramValue的数组是一个数组,其值插入在正确的位置。如果它是一个非索引数组,我们希望对应paramValue的数组是一个将元素推入其上的数组。如果它是一个字符串,我们想在该对象上创建一个常规属性,并将其分配paramValue给它,除非该属性已经存在,在这种情况下,我们想将现有属性转换为paramValue数组,然后将输入推入该数组paramValue
为了说明这一点,这是一些示例输入,以及我们期望的输出:


getAllUrlParams('http://example.com/?colors[0]=red&colors[2]=green&colors[6]=blue');
// { "colors": [ "red", null, "green", null, null, null, "blue" ] }
getAllUrlParams('http://example.com/?colors[]=red&colors[]=green&colors[]=blue');
// { "colors": [ "red", "green", "blue" ] }
getAllUrlParams('http://example.com/?colors=red&colors=green&colors=blue');
// { "colors": [ "red", "green", "blue" ] }
getAllUrlParams('http://example.com/?product=shirt&color=blue&newuser&size=m');
// { "product": "shirt", "color": "blue", "newuser": true, "size": "m" }

这是实现功能的代码:

if (paramName.match(/\[(\d+)?\]$/)) {
  var key = paramName.replace(/\[(\d+)?\]/, '');
  if (!obj[key]) obj[key] = [];
  if (paramName.match(/\[\d+\]$/)) {
    var index = /\[(\d+)\]/.exec(paramName)[1];
    obj[key][index] = paramValue;
  } else {
    obj[key].push(paramValue);
  }
} else {
  if (!obj[paramName]) {
    obj[paramName] = paramValue;
  } else if (obj[paramName] && typeof obj[paramName] === 'string'){
    obj[paramName] = [obj[paramName]];
    obj[paramName].push(paramValue);
  } else {
    obj[paramName].push(paramValue);
  }
}

最后,我们返回带有参数和值的对象。
如果您的网址包含任何编码的特殊字符,例如空格(编码为%20),则您也可以对其进行解码以获取原始值,如下所示:

// assume a url parameter of test=a%20space
var original = getAllUrlParams().test; // 'a%20space'
var decoded = decodeURIComponent(original); // 'a space'

请注意不要解码已经解码的内容,否则脚本将出错,尤其是涉及百分比时。
无论如何,恭喜!现在您知道了如何获取URL参数,并希望在此过程中学到了其他技巧。

结论

本文中的代码适用于最常见的用例,在这些用例中您将获得URL查询参数。如果您要处理任何边缘情况,例如不常见的分隔符或特殊格式,请确保进行相应的测试和调整。
如果你想要做更多的网址,还有诸如提供特定的库,查询字符串Medialize URI.js。但是,由于它基本上是字符串操作,因此仅使用纯JavaScript通常很有意义。无论您使用自己的代码还是使用库,请确保检查所有内容并确保其适用于您的用例。
本文针对相关性和准确性在2020年进行了更新。要获得更深入的JavaScript知识,请阅读我们的书:JavaScript:Ninja的新手,第二版

本文转自:https://www.sitepoint.com/get-url-parameters-with-javascript/