Node 搭建一个静态资源服务器的实现

2020-06-17 05:51:05易采站长站整理

const data = {
files,
dir: dir ? `${dir}` : '' // path.relative可能返回空字符串()
}

const template = ejs.render(sourse.toString(),data)
response.end(template)
}
} catch (err) {
response.statusCode = 404
···
}
}

重启动

$ node server/http.js
就可以看到文件目录的链接:

五、匹配文件 MIME 类型

静态资源有图片、css、js、json、html等,

在上面判断

stats.isFile()
后响应头设置的 Content-Type 都为 text/plain,但各种文件有不同的 Mime 类型列表。

我们先根据文件的后缀匹配它的 MIME 类型:


// server/mime.js
const path = require('path')
const mimeTypes = {
'js': 'application/x-javascript',
'html': 'text/html',
'css': 'text/css',
'txt': "text/plain"
}

module.exports = (filePath) => {
let ext = path.extname(filePath)
.split('.').pop().toLowerCase() // 取扩展名

if (!ext) { // 如果没有扩展名,例如是文件
ext = filePath
}
return mimeTypes[ext] || mimeTypes['txt']}

匹配到文件的 MIME 类型,再使用

response.setHeader('Content-Type', 'XXX')
设置响应头:


// server/route.js
const mime = require('./mime')
···
if (stats.isFile()) {
const mimeType = mime(filePath)
response.statusCode = 200
response.setHeader('Content-Type', mimeType)
fs.createReadStream(filePath).pipe(response)
}

运行 server 服务器访问一个文件,可以看到 Content-Type 修改了:

六、文件传输压缩

注意到 request header 中有 Accept—Encoding:gzip,deflate,告诉服务器客户端所支持的压缩方式,响应时 response header 中使用 content-Encoding 标志文件的压缩方式。

node 内置 zlib 模块支持文件压缩。在前面文件读取使用的是

fs.createReadStream()
,所以压缩是对 ReadStream 文件流。示例 gzip,deflate 方式的压缩:

最常用文件压缩,gzip等,使用,对于文件是用ReadStream文件流进行读取的,所以对ReadStream进行压缩:


// server/compress.js
const zlib = require('zlib')

module.exports = (readStream, request, response) => {
const acceptEncoding = request.headers['accept-encoding']

if (!acceptEncoding || !acceptEncoding.match(/b(gzip|deflate)b/)) {
return readStream
}
else if (acceptEncoding.match(/bgzipb/)) {