这篇文章主要介绍了关于用Node提供静态文件服务,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下
前言
对于一个web应用,提供静态文件(CSS、JavaScript、图片)服务常常是必须的。本文将介绍如何做一个自己的静态文件服务器。
创建一个静态文件服务器
每个静态文件服务器都有个根目录
,也就是提供文件服务的基础目录。所以我们要在即将创建的服务器上定义一个root变量,它将作为我们这个静态文件服务器的根目录:
var http = require('http') var join = require('path').join var fs = require('fs') var root = __dirname
__dirname 在Node中是一个神奇的变量,它的值是该文件所在目录的路径。在本例中,服务器会将这个脚本所在的目录作为静态文件的根目录。
有了文件的路径,还需要传输文件的内容。
这可以用fs.ReadStream
完成,它是Node中Stream类之一。成功调用 fs.createReadStream() 会返回一个新的 fs.ReadStream 对象。
下面的代码实现了一个简单但功能完备的文件服务器。
var server = http.createServer(function(req, res){ let path = join(root, req.url) let stream = fs.createReadStream(path) stream.on('data', function(chunk){ res.write(chunk) }) stream.on('end', function(){ res.end() }) }) server.listen(3000)
这个文件服务器大体能用,但还有很多细节需要考虑。接下来我们要优化数据的传输,同时也精简一下服务器的代码。
用STREAM.PIPE()优化数据传输
虽然上面的代码看上去还不错,但Node还提供了更高级的实现机制:Stream.pipe()
。用这个方法可以极大简化服务器的代码。 优化后代码如下:
var server = http.createServer(function(req, res){ let path = join(root, req.url) let stream = fs.createReadStream(path) stream.pipe(res) }) server.listen(3000)
这种写法,是不是更简单,更清晰了呢?
理解流和管道
流是Node中很重要的一个概念,你可以把Node中的管道想象成水管,如果你想让某个源头(比如热水器)流出来的水流到一个目的地(比如厨房的水龙头),可以在中间加一个管道把它们连起来,这样水就会顺着管道从源头流到目的地。
Node中的管道也是这样,但其中流动的不是水,而是来自源头(即ReadableStream
)的数据,管道可以让它们“流动”到某个目的地(即WritableStream
)。你可以用pipe方法把管道连起来:
ReadableStream.pipe(WritableStream)
读取一个文件(ReadableStream)并把其中的内容写到另一个文件中(WritableStream)用的就是管道:
let readStream = fs.createReadStream('./original.txt') let writeStream = fs.createWriteStream('./copy.txt') readStream.pipe(writeStream)
所有ReadableStream都能接入任何一个WritableStream。比如HTTP请求(req)对
象就是ReadableStream,你可以让其中的内容流动到文件中:
req.pipe(fs.createWriteStream('./req-body.txt'))
运行
现在我们来运行上面的代码,我们在根目录下放一张图片,比如peiqi.jpg。
在浏览器中输入http://127.0.0.1:3000/peiqi.jpg
,发现可爱的peiqi已经出现在你的面前了。peiqi.jpg
被当作响应主体从http服务器送到了客户端(浏览器)。
虽然已经品尝到了成功的滋味,但这个静态文件服务器还不够完整,因为它很容易出错。想象一下,如果用户不小心输入了一个并不存在的资源,比如abc.html,服务器就会马上崩掉。所以我们还得给这个文件服务器加上错误处理机制,让它足够健壮
。
处理服务器错误
在Node中,所有继承了EventEmitter的类都可能会发出error事件。为了监听错误,在fs.ReadStream上注册一个error事件处理器(比如下面这段代码),返回响应状态码500表明有服务器内部错误:
stream.on('error', function(err){ res.statusCode = 500 res.end('服务器内部错误') })
用fs.stat()实现错误处理
我们可以用fs.stat()
来获取文件的相关信息,如果文件不存在,fs.stat()会在err.code中放入ENOENT
作为响应,然后你可以返回错误码404,向客户端表明文件未找到。如果fs.stat()返回了其他错误码,你可以返回通用的错误码500。
重构后的代码如下:
var server = http.createServer(function(req, res){ let path = join(root, req.url) fs.stat(path, function(err, stat) { if (err) { if ('ENOENT' == err.code) { res.statusCode = 404 res.end('Not Found') } else { res.statusCode = 500 res.end('服务器内部错误') } } else { // 有该文件 res.setHeader('Content-Length', stat.size) var stream = fs.createReadStream(path) stream.pipe(res) stream.on('error', function(err) { // 如果读取文件出错 res.statusCode = 500 res.end('服务器内部错误') }) } }) }) server.listen(3000)
注意
本节构建的文件服务器是个简化版。如果你想把它放到生产环境中,应该更全面地检查输入的有效性,以防用户通过目录遍历攻击访问到你本来不想开放给他们的那部分内容。
小结
读到这里,相信聪明的你已经掌握了如何用Node创建一个静态服务器,下一篇文章我会给大家介绍如何用Node处理用户上传的文件并存放到服务器中。
以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!
相关推荐:
以上是用Node提供静态文件服务的详细内容。更多信息请关注PHP中文网其他相关文章!

Python更适合初学者,学习曲线平缓,语法简洁;JavaScript适合前端开发,学习曲线较陡,语法灵活。1.Python语法直观,适用于数据科学和后端开发。2.JavaScript灵活,广泛用于前端和服务器端编程。

Python和JavaScript在社区、库和资源方面的对比各有优劣。1)Python社区友好,适合初学者,但前端开发资源不如JavaScript丰富。2)Python在数据科学和机器学习库方面强大,JavaScript则在前端开发库和框架上更胜一筹。3)两者的学习资源都丰富,但Python适合从官方文档开始,JavaScript则以MDNWebDocs为佳。选择应基于项目需求和个人兴趣。

从C/C 转向JavaScript需要适应动态类型、垃圾回收和异步编程等特点。1)C/C 是静态类型语言,需手动管理内存,而JavaScript是动态类型,垃圾回收自动处理。2)C/C 需编译成机器码,JavaScript则为解释型语言。3)JavaScript引入闭包、原型链和Promise等概念,增强了灵活性和异步编程能力。

不同JavaScript引擎在解析和执行JavaScript代码时,效果会有所不同,因为每个引擎的实现原理和优化策略各有差异。1.词法分析:将源码转换为词法单元。2.语法分析:生成抽象语法树。3.优化和编译:通过JIT编译器生成机器码。4.执行:运行机器码。V8引擎通过即时编译和隐藏类优化,SpiderMonkey使用类型推断系统,导致在相同代码上的性能表现不同。

JavaScript在现实世界中的应用包括服务器端编程、移动应用开发和物联网控制:1.通过Node.js实现服务器端编程,适用于高并发请求处理。2.通过ReactNative进行移动应用开发,支持跨平台部署。3.通过Johnny-Five库用于物联网设备控制,适用于硬件交互。

我使用您的日常技术工具构建了功能性的多租户SaaS应用程序(一个Edtech应用程序),您可以做同样的事情。 首先,什么是多租户SaaS应用程序? 多租户SaaS应用程序可让您从唱歌中为多个客户提供服务

本文展示了与许可证确保的后端的前端集成,并使用Next.js构建功能性Edtech SaaS应用程序。 前端获取用户权限以控制UI的可见性并确保API要求遵守角色库

JavaScript是现代Web开发的核心语言,因其多样性和灵活性而广泛应用。1)前端开发:通过DOM操作和现代框架(如React、Vue.js、Angular)构建动态网页和单页面应用。2)服务器端开发:Node.js利用非阻塞I/O模型处理高并发和实时应用。3)移动和桌面应用开发:通过ReactNative和Electron实现跨平台开发,提高开发效率。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

mPDF
mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

适用于 Eclipse 的 SAP NetWeaver 服务器适配器
将Eclipse与SAP NetWeaver应用服务器集成。

WebStorm Mac版
好用的JavaScript开发工具

MinGW - 适用于 Windows 的极简 GNU
这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

VSCode Windows 64位 下载
微软推出的免费、功能强大的一款IDE编辑器