用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处理用户上传的文件并存放到服务器中。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 使用nodejs、Python写的一个简易HTTP静态文件服务器

    日常开发过程中,我们经常需要修改一些放在 CDN 上的静态文件(如 JavaScript.CSS.HTML 文件等),这个过程中,我们希望能有一种方式将线上 CDN 的目录映射为本地硬盘上的某个目录,这样,当我们在本地修改了某个文件时,不需要发布,刷新后马上能看到效果. 比如,我们的 CDN 域名是:http://a.mycdn.com,本地对应的目录是:D:\workassets,我们希望所有对 http://a.mycdn.com/* 的访问被映射到本地的 D:\workassets\* 下

  • 在windows上用nodejs搭建静态文件服务器的简单方法

    在windows上用nodejs搭建一个静态文件服务器,即使你一点基础没有也能学会nodejs静态文件服务器的搭建,本文介绍的非常详细,很适合零基础入门的朋友学习. 首先安装nodejs: •新建一个node文件夹 •下载node.exe到该文件夹 •下载npm然后解压到该文件夹 •现在node文件夹是这样的 •把该目录加入到path环境变量 •在命令行执行 node -v npm -v 如果得到了版本号则表示nodejs安装完成 •在命令行中执行 npm config set registry

  • Node.js静态文件服务器改进版

    首先还是先感谢github,感谢github上提供此段源码的作者.跟昨晚的来比今天的静态文件服务器有点点复杂些,可以学到很多新的东西. 仔细会发现这次的代码多了一个fs.stat函数和ReadStream对象的pipe函数,stat这个函数是用来获取文件信息.第一个参数是传入文件路径,第二个则是回调函数,回调函数的第二个参数stats的属性为文件的基本信息.pipe函数用于将这个可读流和destination目标可写流连接起来,传入这个流中的数据将会写入到destination流中.通过在必要时

  • 实战node静态文件服务器的示例代码

    本篇文章主要介绍了实战node静态文件服务器的示例,分享给大家,具体如下: 支持功能: 读取静态文件 访问目录可以自动寻找下面的index.html文件, 如果没有index.html则列出文件列表 MIME类型支持 缓存支持/控制 支持gzip压缩 Range支持,断点续传 全局命令执行 子进程运行 1. 创建服务读取静态文件 首先引入http模块,创建一个服务器,并监听配置端口: const http = require('http'); const server = http.create

  • 用Node提供静态文件服务的方法

    前言 对于一个web应用,提供静态文件(CSS.JavaScript.图片)服务常常是必须的.本文将介绍如何做一个自己的静态文件服务器. 创建一个静态文件服务器 每个静态文件服务器都有个根目录,也就是提供文件服务的基础目录.所以我们要在即将创建的服务器上定义一个root变量,它将作为我们这个静态文件服务器的根目录: var http = require('http') var join = require('path').join var fs = require('fs') var root

  • 在Express中提供静态文件的实现方法

    为了提供诸如图像.CSS 文件和 JavaScript 文件之类的静态文件,请使用 Express 中的 express.static 内置中间件函数. 将包含静态资源的目录的名称传递给 express.static 中间件函数,以便开始直接提供这些文件.例如,使用以下代码在名为 public 的目录中提供图像.CSS 文件和 JavaScript 文件: app.use(express.static('public')); 现在,可以访问位于 public 目录中的文件: http://loc

  • python flask中静态文件的管理方法

    Web应用中大多会提供静态文件服务以便给用户更好的访问体验. 静态文件主要包含CSS样式文件,js脚本,图片和字体等. Flask也支持静态文件访问的,默认情况下只需在项目根目录下,创建名为static的目录,在应用中使用'/static'开头的路径就可以访问了.但是为了获得更好的处理能力,推荐使用Nginx 或者其他服务器管理静态文件. 不要直接在模板中写死静态文件路径,应该使用url_for生成路径. 例如: url_for('static',filename='style.css') 生成

  • Node.js静态服务器的实现方法

    当你输入一个url时,这个url可能对应服务器上的一个资源(文件)也可能对应一个目录. So服务器会对这个url进行分析,针对不同的情况做不同的事. 如果这个url对应的是一个文件,那么服务器就会返回这个文件. 如果这个url对应的是一个文件夹,那么服务器会返回这个文件夹下包含的所有子文件/子文件夹的列表. 以上,就是一个静态服务器所主要干的事. 但真实的情况不会像这么简单, 我们所拿到的url可能是错误的,它所对应的文件或则文件夹或许根本不存在, 又或则有些文件和文件夹是被系统保护起来的是隐藏

  • ASP.NET Core静态文件的使用方法

    前言 静态文件(HTML,CSS,图片和Javascript之类的资源)会被ASP.NET Core应用直接提供给客户端. 静态文件通常位于网站根目录(web root) <content-root>/wwwroot文件夹下.通常会把项目的当前目录设置为Content root,这样项目的web root就可以在开发阶段被明确. public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.Cre

  • 解析Go 标准库 http.FileServer 实现静态文件服务

    http.FileServer 方法属于标准库 net/http,返回一个使用 FileSystem 接口 root 提供文件访问服务的 HTTP 处理器.可以方便的实现静态文件服务器. http.ListenAndServe(":8080", http.FileServer(http.Dir("/files/path"))) 访问 http://127.0.0.1:8080,即可看到类似 Nginx 中 autoindex 目录浏览功能. 源码解析 我们现在开始将

  • 如何利用node实现静态文件缓存详解

    目录 缓存 缓存位置分类 缓存设置header node实现静态文件缓存 强缓存 思路 代码实现 效果展示 协商缓存 思路 代码实现 效果展示 总结 缓存 浏览器缓存(Brower Caching)是浏览器对之前请求过的文件进行缓存,以便下一次访问时重复使用,节省带宽,提高访问速度,降低服务器压力 缓存位置分类 memory cache:内存中的缓存,关闭浏览器则清空,一般存储一些js库 disk cache:硬盘中的缓存,关闭浏览器不会马上清空,一般存储大文件,比如 图片资源,iconFont

  • python2.7的flask框架之引用js&css等静态文件的实现方法

    动态 web 应用也会需要静态文件,通常是 CSS 和 JavaScript 文件.理想状况下, 我们已经配置好 Web 服务器来提供静态文件,但是在开发中,Flask 也可以做到. 只要在我们的包中或是模块的所在目录中创建一个名为 static 的文件夹,在应用中使用 /static 即可访问.我们要给静态文件生成 URL ,需要使用特殊的 'static' 端点名: url_for('static', filename='style.css') 这个css文件应该存储在文件系统上的 stat

  • 使用python快速在局域网内搭建http传输文件服务的方法

    在工作和学习中如果同时传输多个文件,大的安装包,python提供了一种无线传输的方法,开启一个本地http服务器,同一局域网下可方便访问 经测试下载速度可达13M/s的稳定速度! 下面分别展示linux下和windows下实现方法 Linux 操作系统 在 Linux 操作系统上安装了 Python 的机器上或者在Linux服务器上,可使用 nohup python -m SimpleHTTPServer [port] & 快速搭建一个http服务. 在 Linux 服务器上或安装了 Pytho

  • Flask中提供静态文件的实例讲解

    1.可以使用send_from_directory从目录发送文件,这在某些情况下非常方便. from flask import Flask, request, send_from_directory # set the project root directory as the static folder, you can set others. app = Flask(__name__, static_url_path='') @app.route('/js/<path:path>') de

随机推荐