)
教程CLI【免费下载链接】learnyounodeLearn You The Node.js For Much Win! An intro to Node.js via a set of self-guided workshops.项目地址https://gitcode.com/gh_mirrors/le/learnyounode点击查看免费下载导读本文围绕 learnyounode 第 9 个练习http_uppercaserer展开讲解如何在 Node.js 中编写一个「只接受 POST 请求、将请求 body 中的字符全部转换为大写并原样返回给客户端」的 HTTP 服务器。通过本练习你将掌握 Node.js 核心模块http的服务器写法、利用request与response的流式能力streaming进行数据转发以及使用through2-map以Array#map()的思维创建 transform stream。读完本文你不仅能独立完成该练习并通过learnyounode verify校验还能把「流式管道 逐块转换」的模式复用到日志格式化、字符过滤、数据清洗等真实场景中。练习任务与验收标准http_uppercaserer是本仓库 exercises/http_uppercaserer/ 目录下的一个自引导练习它的原始任务文档是 problem.md本仓库同时提供了包括简体中文 problem.zh-cn.md 在内的 15 种语言版本。任务描述非常清晰只有两条硬性要求编写一个 HTTP服务器它只接受 POST 形式的请求将 POST 请求主体body所带的字符转换成大写形式然后返回给客户端服务器需要监听由第一个命令行参数process.argv[2]所指定的端口。这里的「只接受 POST」意味着当收到 GET 等其他 HTTP 方法时服务器不应执行大写转换逻辑而应当给客户端一个明确的拒绝响应例如直接返回一段提示文本。推荐解法request/response 流式管道 through2-map练习文档明确提示虽然不限制你对request和response对象是否使用流式处理但使用流会简单得多。这是因为req是一个Readable流数据源res是一个Writable流数据汇二者可以直接用.pipe()连接起来形成「读取 → 转换 → 写出」的数据通道无需手动监听data事件或调用res.write()逐段拼写。npm 生态中有很多可以在数据流过 stream 时进行转换的模块本练习官方推荐的是through2-map理由是它提供了最简单的 API只需一个函数接收一个数据块chunk并返回一个数据块工作方式酷似Array#map()只不过作用对象是 stream。官方文档给出的通用示例是一个「字符反转器」const map require(through2-map) inStream.pipe(map(function (chunk) { return chunk.toString().split().reverse().join() })).pipe(outStream)这段代码揭示了三层要点map()返回一个 transform stream可以直接放进.pipe()链中传入的chunk通常是一个Buffer所以先调用.toString()转成字符串再做处理处理函数的返回值会作为新的数据块继续向outStream传递。需要特别提醒数据块chunk的大小由上游up-stream决定它对传入数据的切分粒度你几乎无法控制——一次 pipe 的 chunk 可能是半句话、一句话或一整段文本。因此你的转换函数必须对「任意大小、任意边界」的文本块都成立这正是本练习要用chunk.toString().toUpperCase()而不是「在 buffer 边界上做字符串反转」这类敏感操作的原因。安装 through2-map在本练习的工作目录中执行$ npm install through2-map如果你没有联网可以手动创建一个node_modules子目录然后从 learnyounode 的安装目录中把整个模块目录完整复制进去源路径对应本仓库中的 node_modules 依赖声明through2-map是 learnyounode 的正式依赖版本为^3.0.0$ mkdir node_modules $ cp -r learnyounode 安装目录/node_modules/through2-map node_modules/through2-map的完整文档也已随 learnyounode 安装到本地可通过浏览器打开本仓库中的 docs/through2-map.html 查看。该文档补充了几个重要语义它只是 aroundthrough2的一层超薄封装super thin wrapper注意你无法跳过skipchunk——它专为「修改」设计若要做过滤应改用through2或through2-filter如果在处理函数中返回null流会在那里终止IMPORTANT与Array.prototype.map的区别不能在流中插入null元素否则中止没有第三个array回调参数因为那需要把整个流物化违背流的初衷可选参数wantStrings: true会自动对 chunk 调用toString()避免在每个处理函数里手动转换其余所有 through2 选项同样适用。官方参考解法逐行剖析仓库在 exercises/http_uppercaserer/solution/solution.js 给出了官方参考实现仅 14 行use strict const http require(http) const map require(through2-map) const server http.createServer(function (req, res) { if (req.method ! POST) { return res.end(send me a POST\n) } req.pipe(map(function (chunk) { return chunk.toString().toUpperCase() })).pipe(res) }) server.listen(Number(process.argv[2]))逐行拆解http.createServer(callback)创建服务器callback在每个请求到达时触发接收req请求流和res响应流req.method ! POST方法校验。非 POST 请求直接res.end()返回提示文本并结束响应不进入转换管道req.pipe(map(...)).pipe(res)核心管道。req的每个数据块进入map()创建的 transform streamchunk.toString()把 Buffer 转成字符串.toUpperCase()完成大写转换转换结果继续流向resserver.listen(Number(process.argv[2]))监听第一个命令行参数指定的端口。注意这里用Number()做了显式类型转换因为process.argv[2]在 shell 中传参时通常是字符串而.listen()对端口做了容错处理字符串也会被隐式转换但显式转换更严谨、可读性更好。值得对比的是测试仓库中的变体写法——test/http_uppercaserer/valid_01.js 用process.argv[2] | 0做按位或取整效果同样是得到数字端口而 invalid_02.js 故意不调用.toUpperCase()直接返回chunk.toString()用来验证校验器能否识破「没做大小写转换」的假答案。后台校验机制验证器如何判定对错了解练习的验证机制能帮你写出一次性通过的标准答案。本练习的校验逻辑集中在 exercises/http_uppercaserer/exercise.js它基于workshopper-exercise框架组装而成filecheck检查提交的脚本文件确实存在execute用spawn()并行启动提交脚本和官方参考解法二者各分配一个随机端口addSetup通过 lib/rndport.js 生成端口——1024 Math.floor(Math.random() * 64511)确保提交脚本与参考解法分别监听submissionPort和solutionPort submissionPort 1并把端口作为唯一参数传入submissionArgs/solutionArgs这就是「第一个命令行参数指定端口」的由来addProcessor把双方的 stdout 替换为自定义的through2()流随后延迟 500ms 发起请求setTimeout(query.bind(this, mode), 500)给服务器留出启动时间query 压力测试在 5 秒内每 50ms 向http://localhost:port发送一次 POST 请求每次写入一行取自 lib/words.js 的随机单词来自boganipsum/clean_words把两个服务器的响应流分别接到各自的 stdout 上5 秒后stream.end()收尾comparestdout最终对比「你的程序 stdout」与「官方解法 stdout」是否完全一致——内容必须一字不差才算 PASS。若连接失败服务器没启动、端口不对、监听失败会触发fail.connection错误提示包含目标地址与错误消息。这对你的启示验证器既不检查你是否用了through2-map也不检查你是否手动data事件它只关心「给定相同 POST 输入输出是否与官方解法逐字相同」。因此你完全可以用req.on(data)res.write()的方式实现同样的结果但流式管道写法更简洁、更符合 Node.js 惯例也更容易通过。测试用例印证测试目录 test/http_uppercaserer/ 里存放着校验器跑批的脚本样例valid_01.js正确解法——方法校验 chunk.toString().toUpperCase()invalid_02.js漏做大小写转换直接返回原样 chunk应被判 FAILinvalid_01.js空文件代表「没写任何代码」的极端失败场景。动手完成练习从创建文件到 verify 通过结合 README.md 中给出的标准工作流完整步骤如下启动练习终端运行learnyounode在菜单中选中HTTP UPPERCASERER阅读打印出来的任务与提示创建文件新建http-uppercaserer.js原英文文档要求文件名必须是http-uppercaserer.js写入上文的正解代码本地自测先手动启动并模拟一次请求确认行为符合预期$ node http-uppercaserer.js 8000 $ curl -s -d hello learnyounode http://localhost:8000 HELLO LEARNYOUNODEcurl -d默认发送application/x-www-form-urlencoded的 POST 请求服务器应返回大写后的字符串。再验证非 POST 被拒绝$ curl -s http://localhost:8000 send me a POST提交校验运行$ learnyounode verify http-uppercaserer.js校验器会同时启动你的脚本与官方参考解法对二者发送完全相同的 POST 数据流逐字比对 stdout。通过则显示 PASS失败会提示是连接问题还是内容不一致。从练习到实战流式转换模式的延伸http_uppercaserer教给你的本质上是一个可复用的架构模式「源流 → transform 流 → 目标流」三明治管道。在真实项目中through2-map的wantStrings选项、处理函数中「返回null终止流」的语义、以及与Array#map的三点差异不能跳块、没有第三个 array 参数、概念上不修改源都是踩坑与设计时需要牢记的边界。例如用wantStrings简化去 HTML 标签的写法源自 docs/through2-map.htmlconst map require(through2-map) const stripTags map({ wantStrings: true }, function (str) { return str.replace(/.*?/g, ) })再比如利用处理函数接收(chunk, index)第二参数实现「每隔一个块插入空行」的格式化同样可以一行完成。掌握这个模式后日志脱敏、字段规整、文本清洗等流式处理任务都可以直接套用而无需手写through2的(chunk, encoding, callback)样板代码。小结本练习是 learnyounode 从「TCP/HTTP 基础」过渡到「流式数据处理」的关键一课。你需要做到三点用http.createServer起服务、用req.method做 POST 方法白名单校验、用req.pipe(map(...)).pipe(res)以流式管道完成「读取—大写转换—写回」。后台的 exercise.js 通过随机端口并行起跑、5 秒持续 POST 压测、stdout 逐字比对的方式自动验收你只要保证输出与官方解法逐字节一致即可通过。而through2-map这一「面向流的Array#map」工具值得沉淀为你 Node.js 工具箱里的常备件。赞分享教程CLI【免费下载链接】learnyounodeLearn You The Node.js For Much Win! An intro to Node.js via a set of self-guided workshops.项目地址https://gitcode.com/gh_mirrors/le/learnyounode点击查看免费下载相关推荐learnyounode 实战用 through2-map 编写 HTTP 大写转换服务器http_uppercasererlearnyounode 实战用 through2 map 编写 HTTP 大写转换服务器http_uppercaserer 本篇技术指南以 learny教程CLIlearnyounode 闯关用 through2-map 编写 HTTP 大写转换服务器HTTP Uppercasererlearnyounode 闯关用 through2 map 编写 HTTP 大写转换服务器HTTP Uppercaserer 导读 本文围绕 learny教程CLIPolar Adapter Utils解读 polar-sh/adapter-utils 的 Webhook 分发与权益Entitlement工具链Polar Adapter Utils解读 polar sh/adapter utils 的 Webhook 分发与权益Entitlement工具链 导教程CLI上一篇抖音无水印批量下载完整指南填个链接视频图集音乐一次拿下下一篇告别生硬动画5个贝塞尔曲线技巧让你的交互设计秒变丝滑创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考