ARTICLE DETAIL

资讯详情

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

learnyounode 实战:用 http 模块与 fs.createReadStream() 编写 HTTP 文件服务器

learnyounode 实战:用 http 模块与 fs.createReadStream() 编写 HTTP 文件服务器 教程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 的HTTP FILE SERVERHTTP 文件服务器练习展开讲解如何用 Node.js 核心模块http搭建一个 HTTP 服务器并通过fs.createReadStream()把磁盘上的文本文件以流的方式streaming响应给每一个请求。读完本文你将掌握http.createServer()的请求/响应流模型、src.pipe(dst)的管道用法以及 learnyounode 如何从源码层面验证你的实现必须使用createReadStream。练习目标文件内容一次读入内存还是流式推送练习要求你创建文件http-file-server.js实现一个 HTTP 服务器每次收到请求都把同一个文本文件的内容作为响应体返回服务器监听第一个命令行参数指定的端口待服务的文件路径由第二个命令行参数提供任务强制要求必须使用fs.createReadStream()将文件内容流式传输到响应而不是fs.readFile()/fs.readFileSync()一次性读入。这个约束点出了 Node.js 流式 I/O 的核心优势对于大文件流式读取可以边读边发避免把整个文件缓冲在内存里。原题说明位于 problem.md对应验证逻辑见 exercise.js。为什么选择 http 模块而不是 net 模块前一个练习time_server使用的是 TCP 层的net模块而本练习要讲 HTTP因此必须切换到 Node 核心的http模块。它和net一样提供createServer()方法但创建出来的是一个能说 HTTP 协议解析请求行、请求头、状态行、响应头等的服务器const http require(http) const server http.createServer(function (req, res) { // request handling logic... }) server.listen(8000)http.createServer()接受一个回调每当服务器收到一个连接一次 HTTP 请求时被调用一次签名固定为function callback (request, response) { /* ... */ }两个参数分别是request代表本次 HTTP 请求的对象用于读取请求头headers、查询字符串query-string等属性response用于向客户端发送数据的对象既包括响应头也包括响应体。值得注意的一点是request和response本身也是 Node 流streamsrequest是可读流response是可写流。这意味着你可以直接使用流的抽象来处理数据的收发这正是本练习用pipe串起文件流和响应流的基础。完整的http模块参考文档见仓库内的 http.html。http.createServer()的返回值就是服务器实例必须调用server.listen(portNumber)才能真正开始监听端口。命令行参数端口与文件路径的读取约定本练习的参数约定与前面的练习一脉相承process.argv[2]服务器监听的端口号process.argv[3]要服务的文本文件路径。参考实现 solution.js 展示了标准的写法use strict const http require(http) const fs require(fs) const server http.createServer(function (req, res) { res.writeHead(200, { content-type: text/plain }) fs.createReadStream(process.argv[3]).pipe(res) }) server.listen(Number(process.argv[2]))注意监听端口时用Number(process.argv[2])做显式转换——listen()对数字端口更可靠避免把字符串形式的端口传入导致歧义。测试用例 valid_01.js 还演示了另一种等价写法process.argv[2] | 0按位或转成整数。响应头中通过res.writeHead(200, { content-type: text/plain })声明200 OK状态与text/plain内容类型方便客户端正确解析文本响应。流式传输核心fs.createReadStream() 与 pipe()fs核心模块同样提供文件的流式 API。fs.createReadStream()会返回一个可读流对象代表命令行参数指定的那个文件。之后用管道方法把数据从一个流导向另一个流src.pipe(dst)把src文件可读流接到dstHTTP 响应可写流上Node 会自动处理背压backpressure文件读得快而网络写不动时流会暂缓读取避免内存被无度占用。于是一行代码就完成了从文件读、往响应写的完整链路fs.createReadStream(process.argv[3]).pipe(res)验证机制它如何确保你真的用了 createReadStream本练习的验证远比比对输出更严格。查看 exercise.js 可以发现验证过程分为三部分1. 随机环境准备与真实 HTTP 请求验证脚本在addSetup阶段生成一个随机的文本文件内容来自boganipsum并把端口 文件路径两个参数注入被验证程序端口由 lib/rndport.js 生成1024 Math.floor(Math.random() * 64511)即 1024~65534 随机端口解决方案与被验证程序各占一个相邻端口。随后通过hyperquest发起真实的http://localhost:portGET 请求并在 5 秒后强制结束连接见query函数。2. 输出比对请求返回的响应体会被当作 stdout 流处理用comparestdout与参考实现的输出逐字节比对因此文件内容必须一字不差。3. fs 调用审计最关键exercise 加载了 my_first_io/wrap.js 这个包装模块它会拦截被验证程序中所有fs方法调用包括fs.promises与util.promisify的变体通过调用栈判断哪些fs方法出自你的主程序并记录到ctx.fsCalls。随后addVerifyProcessor检查这些记录const badCalls Object.keys(exercise.wrapData.fsCalls).filter(function (m) { exercise.emit(fail, exercise.__(fail.no_createReadStream, { method: fs. m () })) return !(/createReadStream/).test(m) })凡是被调用的fs方法名不匹配createReadStream都会被判定为违规并给出fail.no_createReadStream失败提示。也就是说只要你用了fs.readFileSync、fs.readFile等任何其他 fs 方法验证就会失败。测试目录中的反例正好印证了这一点invalid_02.js 用fs.readFileSync(...)读文件后再res.end(...)发送虽然行为正确但违背必须流式的要求会被判失败invalid_03.js 同样以res.end(require(fs).readFileSync(...))一次读入后发送属于同类错误invalid_01.js 是空文件无任何实现自然无法通过。完整可运行版本汇总上述要点一份规范的提交程序如下与仓库参考实现一致use strict const http require(http) const fs require(fs) const server http.createServer(function (req, res) { res.writeHead(200, { content-type: text/plain }) fs.createReadStream(process.argv[3]).pipe(res) }) server.listen(Number(process.argv[2]))保存为http-file-server.js后可以用下面的方式本地试运行需要先通过npm install -g learnyounode安装见 README.mdlearnyounode run http-file-server.js或直接验证正确性learnyounode verify http-file-server.js延伸思考为什么流式是关键考点把本练习与前两个文件 I/O 练习对照起来看learnyounode 的教学线索非常清晰练习fs 用法网络交互核心能力MY FIRST I/OreadFileSync无同步 I/O、缓冲读取MY FIRST ASYNC I/OreadFile无异步回调、非阻塞HTTP FILE SERVERcreateReadStreampipeHTTP流式传输、背压控制从同步读到异步读再到流式读层层递进。本练习要求pipe而非一次读完正是为了让你建立文件不必整体驻留内存的直觉——当文件远大于可用内存时流式方案仍然可以平稳地把内容发送给客户端这正是 Node.js 处理静态文件、日志转发、媒体流等场景的基础模式。之后如果你继续学习 stream-adventureREADME 中推荐的下一站会对pipe与背压有更深入的理解。小结服务器要用http.createServer()而非net.createServer()request/response本身就是流对象端口与文件路径分别来自process.argv[2]与process.argv[3]用fs.createReadStream(file).pipe(res)完成文件到 HTTP 响应的流式输送并显式设置200状态与text/plain内容类型learnyounode 的验证器会通过 wrap.js 审计你的 fs 调用任何不使用createReadStream的实现都会被判定失败从源码层面保证了练习意图的落实。赞分享教程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点击查看免费下载相关推荐GameDevMind 游戏数据库选型与优化从关系型到 NoSQL 缓存的完整实践指南GameDevMind 游戏数据库选型与优化从关系型到 NoSQL 缓存的完整实践指南 游戏服务器的数据层既要支撑账号、支付、统计等强一致性业务又要服务排行教程CLI在 Claude Cowork 中打开并查看 PDFpdf-viewer 插件 /pdf-viewer:open 命令完整实战指南在 Claude Cowork 中打开并查看 PDFpdf viewer 插件 /pdf viewer:open 命令完整实战指南 导读 本文聚焦 Clau教程CLIPlano 全链路追踪实战基于 OpenTelemetry 与 W3C Trace Context 的 AI Agent 可观测性指南Plano 全链路追踪实战基于 OpenTelemetry 与 W3C Trace Context 的 AI Agent 可观测性指南 本文以 Plano 的教程CLI上一篇Naive UI色彩系统扩展自定义调色板与语义化颜色下一篇cxk-ball开发者教程如何自定义关卡和添加新技能创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表