前言

当你使用querystring.parse()或者是url.parse()时会得到一个警告@deprecated — since v11.0.0 - Use the WHATWG URL API.

由于 url.parse() 方法使用一种宽松的非标准算法来解析网址字符串,因此可能会引入安全问题
具体来说,已经确定了主机名欺骗以及用户名和密码处理不当的问题

url.parse()v11.0.0开始被打上@deprecated注解(也不知道叫做注解合不合理,可能是 java 写多了吧),在v16.0.0后被完全移除,同时还一并移除的有url.format() url.resolve()

1
2
3
4
5
6
7
/**
* 在 querystring 的 TS 源码开头已经被打上了 @deprecated 具体说明时候被完全移除目前还不得而知
* 部分注释已被我被删除
* @deprecated Legacy
* @see [source](https://github.com/nodejs/node/blob/v17.0.0/lib/querystring.js)
*/
declare module "querystring" {}
1
2
3
4
5
6
7
8
9
10
11
declare module "url" {
/**
* 在 url 的 TS 源码里 parse() 已经被打上了 @deprecated 从v11.0.0开始,到v16.0.0被移除
* 部分注释已被我被删除
* @since v0.1.25
* @deprecated Legacy: Use the WHATWG URL API instead.
* @param urlString The URL string to parse.
* 部分注释已被我被删除
*/
function parse(urlString: string): UrlWithStringQuery;
}

为什么?

这是因为 nodejs 的url.parse方法采用的传统的urlObject,不符合URL 标准,因此被弃用

WHATWG(Web Hypertext Application Technology Working GroupWeb 超文本应用程序技术工作组)

使用 URL

使用 URL 类对 url 进行操作,详细文档见(可将域名后的 org 改为 cn 看中文文档)

1
2
3
4
5
6
7
8
const urlStr = "https://example.org/foo?name=zhangsan&age=18";
const url = new URL(urlStr);
// searchParams 用的是 URLSearchParams API
const name = url.searchParams.get("name");
const age = url.searchParams.get("age");

console.log(name); // zhangsan
console.log(age); // 18

正文

前面脆皮了那么多内容,现在才是本文的主要内容

我们可以这么写来解析 get 请求的参数
访问: http://localhost:3000/foo?name=zhangsan&age=18

因为我比较懒,我就不写那么多示例代码了,全部塞到一个代码示例里,大家勉强看一下注释吧
为了方便,我封装成了一个库,可以获取POST、GET请求的参数,觉得可以的话可以点个star✨支持一下😁
项目地址: Body-Data: https://github.com/Lete114/Body-Data

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
const http = require("http");

const server = http.createServer((req, res) => {
if (req.url === "/favicon.ico") return res.end();

// req.url含问号前面的内容: /foo?name=zhangsan&age=18
console.log(req.url);

// 也可以使用以下两行代码移除 ?"问号" 前面的内容
// const index = url.indexOf('?') + 1
// const string = url.substring(index)
// const query = new URLSearchParams(string);

// 这是为了解析出search,search不含 ?"问号" 前面的内容
// 也就是 name=zhangsan&age=18
const url = new URL(req.url, `http://${req.headers.host}/`);
const query = new URLSearchParams(url.search);

console.log(query.get("name")); // zhangsan
console.log(query.entries()); // URLSearchParams Iterator { [ 'name', 'zhangsan' ], [ 'age', '18' ] }
console.log(query.keys()); // URLSearchParams Iterator { 'name', 'age' }

// 定义一个空对象
const params1 = {};
// 如果for循环内只有1行代码是可以简写成1行的,如下
for (const i of query.keys()) params1[i] = query.get(i);

// 使用entries()也可以
const params2 = {};
for (const i of query.entries()) params2[i[0]] = i[1];

// 使用 Object.fromEntries()
const params3 = Object.fromEntries(query);

console.log(params1); // { name: 'zhangsan', age: '18' }
console.log(params2); // { name: 'zhangsan', age: '18' }
console.log(params3); // { name: 'zhangsan', age: '18' }

res.end(JSON.stringify(params3));
});

server.listen(3000);