是否存在用于解析 URL 路径段(矩阵)参数的 javascript 库?

Does a javascript library for parsing URL path segment (matrix) parameters exist?

鉴于 URL:

var urlString = "http://somehost:9090/cars;color=red;make=Tesla?page=1&perPage=10"

我想要一些 javascript(节点)库,我可以用它来获取汽车路径段的矩阵参数(颜色和品牌),例如:

var url = URL.parse(urlString)
url.pathSegments["cars"].params

会产生

{
  "color": "red",
  "make": "Tesla"
}

此外,理想情况下,这样的库应该考虑对路径段参数的正确解码,这与查询参数的解码不同。

这些参数(连同一堆其他有关 url 的有用信息)在以下文章中有更详细的描述:

https://www.talisman.org/~erlkonig/misc/lunatech%5Ewhat-every-webdev-must-know-about-url-encoding/

我已经进行了大量的谷歌搜索,但一无所获,但希望我只是瞎了眼!

我找到了 URI.js。但是,如果您不想使用该库,我认为这个函数可以满足您的需求(不太确定 decodeURIComponent):

var urlString = "http://somehost:9090/cars;color=red;make=Tesla?page=1&perPage=10"

var getParams = function (urlString) {
    return decodeURIComponent(urlString) // decode the URL (?)
        .match(/\/((?!.+\/).+)\?/)
            // the regex looks for a slash that is NOT
            // followed by at least one character and eventually another slash
            // given var urlString = "http://somehost:9090/cars;color=red;make=Tesla?page=1&perPage=10"
            // we don't want        -------^              ^                         ^
            // we want this slash                   ------|                         |
            // all the way until this question mark --------------------------------|
            // regex explanation:
            /*
                \/                  first slash
                (                   open capturing group
                    (?!             lookbehind for NOT
                        .+\/        any character followed by a slash (/)
                    )
                    .+              capture one or more characters (greedy) past
                )                   the close of the capturing group and until
                \?                  a question mark
            */
        [1] // match will return two groups, which will look like:
            // ["/cars;color=red;make=Tesla?", "cars;color=red;make=Tesla"]
            // we want the second one (otherwise we'd have to .slice(1,-1) the string)
        .split(";")
            // split it at the semicolons
            // if you know you're always going to have "name" followed by a semicolon,
            // you might consider using .slice(1) on this part, so you can get rid of 
            // the if statement below (still keep the p[c[0]] = c[1] part though )
        .reduce(function (p, c) {
            // split it at the equals sign for a key/value in indices 0 and 1
            c = c.split("=");
            // if the length is greater than one, aka we have a key AND a value
            // e.g., c == ["color", "red"]
            if (c.length > 1) {
                // give the previous object a key of c[0] equal to c[1]
                // i.e., p["color"] = "red"
                p[c[0]] = c[1];
            }
            return p; // return p, so that we can keep adding keys to the object
        }, {}); // we pass an object, which will act as p on the first call
}

console.log(getParams(urlString));  // { color: "red", make: "Tesla" }

除了正则表达式,您还可以使用我在上面的评论中发布的内容:

urlString.split("?")[0].split("/").pop().split(";").reduce( /* etc */)

现在我想要一辆特斯拉……

最近写了一个Node.js解析矩阵参数的中间件。 我已经指定了它遵循的规则以及它生成的输出格式。

例如,这是您的 app.js 的样子:

let app = require ('express') (),
  matrixParser = require ('matrix-parser');

app.use (matrixParser ());

app.get ('/cars*', (req, res) => {
  //notice the asterisk after '/cars'
  console.log (JSON.stringify (req.matrix, null, 2));
  res.send ('Thanks=)');
});

app.listen (9090);

您的 URI 如下所示:

http://localhost:9090/cars;color=red;make=Tesla?page=1&perPage=10

然后,您可以像这样使用 curl 测试矩阵解析器功能:

curl "http://localhost:9090/cars;color=red;make=Tesla?page=1&perPage=10"

然后req.matrix设置为以下对象:

[
  {
    "segment": "cars",
    "matrix": {
      "color": "red",
      "make": "Tesla"
    }
  }
]

查询字符串(页面,per_page)保持不变(您只需编写 req.query 即可看到)

现在写答案可能为时已晚,但将来可能会派上用场。

这是回购协议: https://github.com/duaraghav8/matrix-parser

npm install matrix-parser

编辑:很抱歉之前没有提供更详尽的代码答案,这是我对 SO 的第一次贡献,我会花一些时间来掌握它。