ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Node.js 学习笔记:querystring 模块——URL 查询字符串的解析与拼接实战

Node.js 学习笔记:querystring 模块——URL 查询字符串的解析与拼接实战 文档教程后端【免费下载链接】nodejs-learning-guideNodejs学习笔记以及经验总结公众号程序猿小卡项目地址https://gitcode.com/gh_mirrors/no/nodejs-learning-guide点击查看免费下载在 Node.js 服务端开发中解析 URL 查询参数Query String与拼接请求参数是最高频的操作之一无论是处理 HTTP GET 请求携带的?nickcasperage24还是解析application/x-www-form-urlencoded类型的 POST 表单体都离不开querystring模块。本文基于本项目仓库nodejs-learning-guide的 模块/querystring.md 笔记展开结合仓库内多个真实可运行的 demo 源码系统讲解querystring.parse()、querystring.stringify()的完整用法、自定义分隔符技巧并给出 GET / POST 两种典型服务端场景的完整代码帮助你彻底掌握这一小而美的内置模块。模块概述Node.js 内置了querystring模块专门用于 URL 查询参数的解析与拼接API 极其简洁。使用前无需安装任何依赖直接require即可var querystring require(querystring);模块总共提供了四个方法在日常开发中绝大部分场景只会用到前两个方法作用使用频率.parse(str[, sep[, eq[, options]]])将查询参数字符串解析为易于分析的 JSON 对象极高.stringify(obj[, sep[, eq[, options]]])与.parse()相反将对象拼接为查询参数字符串极高.escape(str)对字符串做百分号编码URL 编码供内部及特殊场景使用低.unescape(str)对字符串做百分号解码是escape的逆操作低其中.escape()与.unescape()是内部编码/解码工具源码中parse()与stringify()的编解码行为正是基于它们实现感兴趣的同学可以自行查阅 Node.js 官方文档深入。两个核心方法的完整签名如下querystring.parse(str[, sep[, eq[, options]]]) querystring.stringify(obj[, sep[, eq[, options]]])下面分别展开讲解。查询参数解析querystring.parse()完整语法querystring.parse(str[, sep[, eq[, options]]])parse()把形如nickcasperage24的字符串解析成对象。其中sep是键值对之间的分隔符默认eq是键与值之间的分隔符默认。第四个参数optionsmaxKeys上限、自定义decodeURIComponent解码函数几乎不会用到本文不做展开。先看最简单的默认用法var querystring require(querystring); var str nickcasperage24; var obj querystring.parse(str); console.log(JSON.stringify(obj, null, 4));输出如下{ nick: casper, age: 24 }可以看到每个键值对被解析成了对象的属性值为字符串类型。这里有一个容易忽略的细节parse()解析出的所有值都是字符串例如age: 24中的24并不是数字做数值运算前需要自行转换。自定义分隔符 sep 与 eq再来看sep、eq的作用相当于可以把默认的、替换为自定义字符。对于下面这种参数内嵌套参数的场景用默认分隔符解析会很别扭而自定义分隔符可以一步到位var str1 nickcasperage24extraname-chyingp|country-cn; var obj1 querystring.parse(str1); var obj2 querystring.parse(obj1.extra, |, -); console.log(JSON.stringify(obj2, null, 4));先解析外层得到obj1.extra name-chyingp|country-cn再以|作为键值对分隔符、-作为键值分隔符解析该字段输出如下{ name: chyingp, country: cn }这类技巧在解析自定义格式的子串例如 URL 中嵌入的过滤条件、追踪参数时相当省事无需先split再逐段处理。关于解码行为parse()内部默认使用decodeURIComponent对键和值做百分号解码因此nick%E7%A8%8B%E5%BA%8F%E7%8C%BF%E5%B0%8F%E5%8D%A1会被解析为nick: 程序猿小卡。这与 模块/url.md 中提到的url.parse(str, true)行为一致url 模块在parseQueryString为true时同样依赖 querystring 解析query字段。查询参数拼接querystring.stringify()完整语法querystring.stringify(obj[, sep[, eq[, options]]])stringify()相当于parse()的逆向操作把一个对象拼接成查询参数字符串。默认情况下键值对之间用连接、键与值之间用连接。直接看代码var querystring require(querystring); var obj1 { nick: casper, age: 24 }; var str1 querystring.stringify(obj1); console.log(str1); var obj2 { name: chyingp, country: cn }; var str2 querystring.stringify(obj2, |, -); console.log(str2);输出如下nickcasperage24 name-chyingp|country-cn与parse()相对应第二个参数sep指定键值对分隔符默认第三个参数eq指定键值分隔符默认。需要特别提醒手动指定自定义分隔符时parse()与stringify()必须使用同一组sep/eq才能正确配对否则会解析错乱。编码行为stringify()内部使用escape对键和值做百分号编码后再拼接。例如对象{ nick: 程序猿小卡 }会被序列化为nick%E7%A8%8B%E5%BA%8F%E7%8C%BF%E5%B0%8F%E5%8D%A1。因此当需要把对象拼进 URL 时直接用stringify()即可保证参数在网络传输与解析过程中不会因特殊字符而串扰。实战GET 请求查询参数解析在 HTTP 服务端查询参数通常藏在req.url中。仓库中的 examples/2017.04.08-http-req/get.js 展示了最经典的组合拳先用url.parse()取出查询字符串再用querystring.parse()转成对象var http require(http); var port 3001; var url require(url); var querystring require(querystring); var server http.createServer(function(req, res, next){ var reqUrl req.url; // 访问地址/get?nickchyingpgenderman var query url.parse(reqUrl).query; // 请求参数nickchyingpgenderman var queryObj querystring.parse(query); // 解析后的请求参数{ nick: chyingp, gender: man } res.end(ok); }); server.listen(port, function(){ console.log(listening on port: %s, port); });类似的实现还出现在 examples/2016.11.08-node-http/serverReq/getClientGetQuery.js 中其核心链路完全一致var urlObj url.parse(req.url); var query urlObj.query; var queryObj querystring.parse(query); console.log( JSON.stringify(queryObj) );需要注意的是这里url.parse()默认parseQueryStringfalse返回的query是未解码的原始字符串真正的解码发生在querystring.parse()这一步。如果你想让url.parse()直接给出对象也可以传入第二个参数true内部同样是交给 querystring 解析。实战POST 表单体application/x-www-form-urlencoded解析当客户端以Content-Type: application/x-www-form-urlencoded提交表单时请求体本身就是一个查询字符串例如nickchyingpgenderman。此时需要先在data事件中收集 Buffer 数据再整体交给querystring.parse()。仓库中的 examples/2017.04.08-http-req/post/x-www-form-urlencoded.js 给出了服务端完整实现var http require(http); var port 3001; var url require(url); var querystring require(querystring); var server http.createServer(function(req, res, next){ // POST /post HTTP/1.1 // Content-Type: application/x-www-form-urlencoded // nickchyingpgenderman var contentType req.headers[content-type]; // application/x-www-form-urlencoded var method req.method; var chunk Buffer.alloc(0); req.on(data, function(buf){ chunk Buffer.concat([chunk, buf]); }); req.on(end, function(){ var obj querystring.parse( chunk.toString() ); res.end(obj); // nickchyingpgenderman }); }); server.listen(port, function(){ console.log(listening on port: %s, port); });同样的模式也出现在 examples/2017.05.20-express-body-parser/parser-urlencoded/server.js 中配合content-length或 Buffer 收集来读取完整请求体后解析req.on(end, () { chunks Buffer.concat(arr); done(chunks); }); // ... var body querystring.parse( chunks.toString() ); res.end(Your nick is ${body.nick});可以看出express 的urlencoded类型 body-parser其底层解析思路正是 querystring.parse。理解这一点后即使不用 express你也能手写一个极简的表单解析中间件。实战客户端用 stringify() 发送 POST 数据与服务端解析对应客户端在发送表单数据前需要先用querystring.stringify()把对象序列化为请求体。仓库中的 examples/2016.11.08-node-http/client/requestPost.js 完整演示了这一过程并特别注释了关键步骤var http require(http); var querystring require(querystring); var createClientPostRequest function(){ var options { method: POST, protocol: http:, hostname: 127.0.0.1, port: 3000, path: /post, headers: { connection: keep-alive, content-type: application/x-www-form-urlencoded } }; // 发送给服务端的数据 var postBody { nick: chyingp }; // 创建客户端请求 var client http.request(options, function(res){ // 最终输出Server got client data: nickchyingp res.pipe(process.stdout); }); // 发送的报文主体记得先用 querystring.stringify() 处理下 client.write( querystring.stringify(postBody) ); client.end(); }; // 服务端程序只是负责回传客户端数据 var server http.createServer(function(req, res){ res.write(Server got client data: ); req.pipe(res); }); server.listen(3000, createClientPostRequest);注意两点一是请求头必须带上Content-Type: application/x-www-form-urlencoded服务端才知道按表单格式解析二是client.write()写入的是stringify()后的字符串。同样的发送方式还出现在 examples/2017.05.20-express-body-parser/parser-urlencoded/client.js 中var postBody { nick: chyingp }; var client http.request(options, (res) { res.pipe(process.stdout); }); client.end( querystring.stringify(postBody) );注意事项适用范围querystring只处理keyvaluekeyvalue这种x-www-form-urlencoded格式。对于multipart/form-data常见于文件上传并不适用需要像 examples/2017.04.08-http-req/post/form-data.js 那样按boundary边界手动拆分解析这也解释了为什么会有专门的 multer、body-parser 等中间件来处理复杂表单。值都是字符串parse()得到的所有字段值均为字符串类型需要参与数值运算时请先Number()转换。分隔符一致性自定义sep/eq后parse()与stringify()必须使用同一组参数配对否则数据无法还原。与 url 模块的分工url.parse()负责拆分 URL 的协议、主机、路径等结构querystring.parse()只负责处理其中的查询字符串部分两者配合使用见 模块/url.md 与上文 GET 示例。小结querystring是 Node.js 内置模块中小而美的典型两个核心方法覆盖了查询参数解析与拼接的全部日常需求默认分隔符、符合表单与 URL 通用约定自定义sep/eq又能应对嵌套参数等特殊格式。结合本仓库 examples/2017.04.08-http-req 与 examples/2016.11.08-node-http 中的可运行 demo你可以在本地直接node运行验证文中全部示例。掌握了它无论手写 HTTP 服务还是阅读 body-parser 等中间件源码都会更加得心应手。赞分享文档教程后端【免费下载链接】nodejs-learning-guideNodejs学习笔记以及经验总结公众号程序猿小卡项目地址https://gitcode.com/gh_mirrors/no/nodejs-learning-guide点击查看免费下载相关推荐Next.js 路由跳转用 URL 对象调用 router.push 替代字符串拼接TIL 笔记实战Next.js 路由跳转用 URL 对象调用 router.push 替代字符串拼接TIL 笔记实战 本文基于 TILToday I Learned仓文档教程知识库CANN / ops-nn MSE损失梯度算子MseLossV2Grad 产品支持情况 |产品 | 是否支持 | |: |: :| | term Ascend 950PR/Ascend 950DT/te人工智能算子库深度学习CANNAscendwp-calypso route-modal 模块实战用 URL 查询字符串控制模态框开关的 useRouteModal 与 withRouteModal 实现解析wp calypso route modal 模块实战用 URL 查询字符串控制模态框开关的 useRouteModal 与 withRouteModal 实前端CMS上一篇告别数据丢失风险autojump数据库备份与性能优化实战指南下一篇BullshitGenerator性能测试一秒能生成多少句“人生哲理”创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表