创建静态文件服务器既要用到 Node 内置的功能,也要用第三方的 mime 附加模块来确定文件的 MIME 类型。
先从程序的主文件开始,请在项目根目录下创建 server.js 文件,使用 Node 中跟 HTTP 相关的功能、跟文件系统交互的功能,以及确定文件 MIME 类型的功能。变量 cache 是用来缓存文件中的数据的。
1 | var http = require('http'); |
2 | var fs = require('fs'); |
3 | var path = require('path'); |
4 | var mime = require('mime'); |
5 | var cache = {}; |
1.发送文件数据及错误响应
接下来要添加三个辅助函数以提供静态HTTP文件服务。第一个是在所请求的文件不存在时发送404错误的。把下面的辅助函数加到 server.js 中:
1 | function send404(response) { |
2 | response.writeHead(404, { 'Content-Type': 'text/plain' }); |
3 | response.write('Error 404: resource not found'); |
4 | response.end(); |
5 | } |
第二个辅助函数提供文件数据服务。这个函数先写出正确的HTTP头,然后发送文件的内容。把下面的代码添加到 server.js 中:
1 | function sendFile(response, filePath, fileContents) { |
2 | response.writeHead(200, { "Content-Type": mime.getType(path.basename(filePath)) }); |
3 | response.end(fileContents); |
4 | } |
访问内存(RAM)要比访问文件系统快得多,所以Node程序通常会把常用的数据缓存到内存里。只有第一次访问的时候才会从文件系统中读取。下一个辅助函数会确定文件是否缓存了,如果是,就返回它。如果文件还没被缓存,它会从硬盘中读取并返回它。如果文件不存在,则返回一个HTTP 404错误作为响应。把这个辅助函数加到server.js 中:
1 | function serveStatic(response, cache, absPath) { |
2 | if (cache[absPath]) { |
3 | sendFile(response, absPath, cache[absPath]) |
4 | } else { |
5 | fs.exists(absPath, function(exists) { |
6 | if (exists) { |
7 | fs.readFile(absPath, function(err, data) { |
8 | if (err) { |
9 | send404(response) |
10 | } else { |
11 | cache[absPath] = data |
12 | sendFile(response, absPath, data) |
13 | } |
14 | }) |
15 | } else { |
16 | send404(response) |
17 | } |
18 | }) |
19 | } |
20 | } |
- 创建HTTP服务器
在创建HTTP服务器时,需要给 createServer 传入一个匿名函数作为回调函数,由它来处理每个HTTP请求。这个回调函数接受两个参数: request 和 response 。在这个回调执行时,HTTP 服务器会分别组装这两个参数对象,以便你可以对请求的细节进行处理,并返回一个响应。
将下面代码清单中的逻辑添加到server.js中以创建HTTP服务器。
1 | var server = http.createServer(function(request, response) { |
2 | var filePath = false; |
3 | if (request.url == '/') { |
4 | filePath = 'public/index.html' |
5 | } else { |
6 | filePath = 'public' + request.url; |
7 | } |
8 | var absPath = './' + filePath; |
9 | serveStatic(response, cache, absPath) |
10 | }) |
3.启动HTTP服务器
现在你已经写好了创建 HTTP 服务器的代码,但还没添加启动它的逻辑。添加下面这些代码,它会启动服务器,要求服务器监听 TCP/IP 端口 3000 。 3000 是随便选的,所有 1024 以上的未用端口应该都可以(如果在 Windows 上运行,1024以下的端口也行,或者在 Linux 及 OS X 中用 root 这样的特权用户启动程序也可以)。
1 | server.listen(3000, function() { |
2 | console.log("Server listening on port 3000") |
3 | }) |
在命令行中输入下面这条命令启动服务器:
1 | node server |
服务器运行起来后,在浏览器中访问 http://127.0.0.1:3000 ,如果遇到找不到的文件会激发 404 错误辅助函数,页面上会显示“Error 404: resource not found。”消息。记住,在命令行中按下Ctrl-C可以停止正在运行的服务器。