在 nodejs 中,之前一直推荐的是url.parse
方法来解析参数,不过这个方法已经不推荐了,现在推荐的是 WHATWG 网址的 API。
因为网上找到的都还是之前的方法,这里特此记录下,在 nodejs 中,如何使用 URL 类 或 URLSearchParams 类来获取请求的参数。
1. 创建一个服务 #
我们先用http.createServer
来创建一个简单的 http 服务:
const http = require('http');
http
.createServer((req, res) => {
res.end('hello world');
})
.listen(8080, '127.0.0.1');
在 nodejs 中起一个服务还是很简单的。
2. URL 的使用 #
我们在获取参数前,先讲解下URL
的使用方式。
URL 在浏览器和 nodejs 都可以支持,在 nodejs 中,是在 8.0.0 版本添加上的。
我们在 nodejs 的 http 服务中,可以通过req.url
获取到请求的路径和携带的参数:
const url = '/api?a=1&b=2&c=ccc'; // req.url
2.1 解析 url #
那么我们可以通过 URL 类来解析这个 url。但要注意的是:
若只给 URL 传入一个参数,这个 url 必须是绝对地址,即需要携带协议,若 http://, https://, file://等;若不确定第一个参数中是否携带协议和主机信息,我们可以使用第二个参数进行补充。
当第 1 个参数含有协议和主机,则直接使用;否则会使用第 2 个参数中的信息进行补全。
我们来测试几个:
new URL('/api?a=1'); // Uncaught TypeError: Failed to construct 'URL': Invalid URL
new URL('//www.qq.com'); // Invalid URL 解析错误
new URL('//www.qq.com', 'htts://example.com'); // 正确解析,origin: https://www.xiabingbao.com
new URL('http://www.qq.com', 'https://example.com'); // 正确解析,还是使用自己的http协议, http://www.qq.com
new URL('/api?a=1', 'https://example.com'); // 正确解析,href: https://example.com/api?a=1
可以看到第 1 个参数若是绝对地址,则直接使用;否则会将第 2 个参数与第 1 个参数拼接后,再进行解析。
2.2 解析参数 #
那么该如何解析参数呢?参数已经在实例的searchParams
属性中,这个属性也是URLSearchParams的实例。
const uu = new URL('/api?a=1&b=2&c=ccc', 'https://example.com');
const { searchParams } = uu;
searchParams.get('a'); // '1'
searchParams.get('b'); // '2'
searchParams.get('c'); // 'ccc'
searchParams.get('d'); // null
searchParams.has('a'); // 是否有参数a
[...searchParams.values()]; // 所有数值的集合 ['1', '2', 'ccc']
[...searchParams.keys()]; // 所有key的集合['a', 'b', 'c']
searchParams.forEach(console.log); // 循环所有的数据
searchParams.getAll('a'); // 获取所有的参数a ['1']
searchParams 中的keys()
, values()
, entries()
等属于迭代器的方法。无法直接获取到一个 json 结构的数据,那么如何构造呢?
2.3 如何序列化参数 #
这里没有直接的方法来获取,我们需要通过迭代器的循环来自己实现,关于迭代器的知识,请参考https://es6.ruanyifeng.com/#docs/iterator:
const obj = {};
for (let [key, value] of searchParams) {
obj[key] = value;
}
console.log(obj);
这样就可以得到一个 object 类型的数据了。
3. nodejs 中的使用 #
我们在上面已经了解了 URL 的使用方法,在 nodejs 中怎么使用呢?
const http = require('http');
http
.createServer((req, res) => {
const { searchParams } = new URL(req.url, 'https://example.com');
const username = searchParams.get('username') || 'wenzi';
res.end(`${username}, hello world\n`);
})
.listen(8080, '127.0.0.1');
解析完毕。
当我们向接口发起请求并携带 username 参数时,接口就会对应的数据,这就说明解析成功了。