用Node提供静态文件服务

这篇文章主要介绍了关于用node提供静态文件服务,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下

前言

对于一个web应用,提供静态文件(CSS、JavaScript、图片)服务常常是必须的。本文将介绍如何做一个自己的静态文件服务器。

创建一个静态文件服务器

每个静态文件服务器都有个根目录,也就是提供文件服务的基础目录。所以我们要在即将创建的服务器上定义一个root变量,它将作为我们这个静态文件服务器的根目录:

var http = require('http')var join = require('path').joinvar 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服务器送到了客户端(浏览器)。
405061481-5b3e2651bac82_articlex[1].jpg

虽然已经品尝到了成功的滋味,但这个静态文件服务器还不够完整,因为它很容易出错。想象一下,如果用户不小心输入了一个并不存在的资源,比如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处理文件上传

通过ES6写法去对Redux部分源码解读

以上就是用Node提供静态文件服务的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2746980.html

(0)
上一篇 2025年3月8日 04:15:12
下一篇 2025年3月7日 13:24:38

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • 利用javascript判断浏览器类型

    这篇文章主要介绍了关于利用javascript判断浏览器类型,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 判断浏览类型的相关方法 控制台打印浏览器相关信息 window.navigator.userAgent.toLowe…

    编程技术 2025年3月8日
    200
  • 浏览器与NodeJS的EventLoop异同以及部分机制

    这篇文章主要介绍了关于浏览器与nodejs的eventloop异同以及部分机制,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 浏览器与NodeJS的EventLoop异同,以及部分机制 javascript 是一门单线程的脚…

    2025年3月8日 编程技术
    200
  • JavaScript创建对象的四种方式

    这篇文章主要介绍了关于javascript创建对象的四种方式 ,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 关键字 Object.create; new Object(); new Fn(); {} 背景 此段可跳过不读……

    编程技术 2025年3月8日
    200
  • NodeList 和 HTMLCollection 和 Array的解析

    这篇文章主要介绍了关于nodelist 和 htmlcollection 和 array的解析,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 Array,NodeList, HTMLCollection这三个概念和它们之间的…

    2025年3月8日 编程技术
    200
  • vue的父子组件,父子组件传值和vuex的浅析

    这篇文章主要介绍了关于vue的父子组件,父子组件传值和vuex的浅析,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 一、vue的父子组件之间是如何传值的?  首先呢,需要说说的是,vue既然有双向绑定,那为何会有父子组件之间…

    编程技术 2025年3月8日
    200
  • vue 实现数字滚动增加效果

    这篇文章主要介绍了关于vue 实现数字滚动增加效果 ,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 项目中需要做数字滚动增加的效果,一开始很懵,研究了一下原理,发现很简单,贴出来分享一下 ^_^ 数字滚动组件: 0 expo…

    编程技术 2025年3月8日
    200
  • Jquery添加loading过渡遮罩

    这篇文章主要介绍了关于jquery添加loading过渡遮罩 ,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 用webpack打包一个h5项目,css也打包在bundle.js里,加载稍慢就会有有几秒钟页面呈现出一个没有样式…

    2025年3月8日
    200
  • JS实现希尔排序

    这篇文章主要介绍了关于js实现希尔排序 ,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 希尔排序本质上是一种插入排序,但是对数列进行了等间隔分组处理,在每一组中做插入排序,这一优化使得原本 O(n^2)  的时间复杂度一下降…

    2025年3月8日 编程技术
    200
  • JS实现归并排序

    这篇文章主要介绍了关于js实现归并排序,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 递归的内存堆栈分析 一直对递归理解不深,原因是递归的过程很抽象,分析不清内存堆栈的返回过程。偶然google到一篇博文递归(不得不说,技术…

    2025年3月8日
    200
  • 原生JS基于window.scrollTo()封装垂直滚动动画工具函数

    这篇文章主要介绍了关于原生js基于window.scrollto()封装垂直滚动动画工具函数 ,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 概要: 原生JS基于window.scrollTo()封装垂直滚动动画工具函数,可…

    编程技术 2025年3月8日
    200

发表回复

登录后才能评论