相关文章
- P01: 从实用角度出发的node.js学习教程
- P02:node基本使用
- P03:node内置模块path
- P04:nodeAPI 之 Buffer
- P05:node内置模块 之 events
- P06:node内置模块 fs(1)
- P07:node内置模块 fs(2)
- P08:node实现静态服务器 ~ 创建项目
- P09:node实现静态服务器 ~ hello http
- P10:node实现静态服务器 ~ 静态读取文件或文件夹
- P11:node实现静态服务器 ~ 初步优化体验
- P12:node实现静态服务器 ~ Content-Type优化设置
纵观代码实现,我们所有的
MIME
类型只有两种,这时候会出现一个问题,项目中从出现图片,视频文本文件,就不会输出给我们正确的Content-Type
。虽然大多数高级浏览器还是会在设置错误的情况下依输出正确。但是这并不能成为我们忽视这一项配置的原因。在接口调用或者其他使用中,我们经常活判断Content-Type
类型,以此做出相应的响应。
为了严谨,解决它!解决它!解决它!
文件类型 Content-Type
Content-Type
:即是Internet MediaType
,互联网媒体类型,也叫做MIME
类型。 用于定义网络文件的类型和网页的编码,决定浏览器将以什么形式、什么编码读取这个文件
-
我们出于学习得目的在此贴出一个常用的
MIME
类型对应关系。类型不全,商业项目慎用const mimeTypes = { 'css': 'text/css', 'gif': 'image/gif', 'html': 'text/html', 'ico': 'image/x-icon', 'jpeg': 'image/jpeg', 'jpg': 'image/jpeg', 'js': 'text/javascript', 'json': 'application/json', 'pdf': 'application/pdf', 'png': 'image/png', 'svg': 'image/svg+xml', 'swf': 'application/x-shockwave-flash', 'tiff': 'image/tiff', 'txt': 'text/plain', 'wav': 'audio/x-wav', 'wma': 'audio/x-ms-wma', 'wmv': 'video/x-ms-wmv', 'xml': 'text/xml' }
代码修改
header
下属新建mime.js
<!--核心代码-->
module.exports = (filePath) => {
// 截取文件后缀名
let ext = path.extname(filePath)
.split('.')
.pop()
.toLowerCase()
// 如果无法截取文件后缀 例如一些配置文件
if (!ext) {
ext = filePath
}
// 不存在及作为普通文本处理
return mimeTypes[ext] || mimeTypes['txt']
}
header
下属的route.js
修改为
效果
修正为:展示问题
我们既然拿到了文件的类型,也请求头中设置了相应
MIME
,但是总去浏览器后台查看也太蠢了,需要对文件做页面内标识
-
为了方便查看贴出文件全部代码
route.js
const fs = require('fs') const path = require('path') const promisify = require('util').promisify const stat = promisify(fs.stat) const readdir = promisify(fs.readdir) const conf = require('../config/defaultConfig') // 引入模板 const Dir = require('../template/dir') // 引用mime 文件 const mimeType = require('../header/mime') module.exports = async function(rep, res, filePath) { // 规避此问题require-atomic-updates报告在异步函数中重新分配变量时可能发生的竞争条件错误 const awaitRes = await res try { const stats = await stat(filePath) if (stats.isFile()) { const mimeTypes = mimeType(filePath) awaitRes.writeHead(200, { 'Content-Type': mimeTypes }) // 如果是文件 返回文件内容 awaitRes.statusCode = 200 fs.createReadStream(filePath).pipe(awaitRes) } else if (stats.isDirectory()) { awaitRes.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' }) // 如果是文件夹,返回文件列表 const files = await readdir(filePath) awaitRes.statusCode = 200 // 路径 const dir = path.relative(conf.root, filePath) const filesArr = files.toString().split(',') // 置换为数组 const data = { title: path.basename(filePath), dir: dir ? `/${dir}` : '', // 需要注意一点`path.relative` 是相对与根路径计算的,如果我们真的访问根路径就会返回空 files: filesArr.map(item => { return { fileName: item, icon: mimeType(item) } }) } awaitRes.end(Dir(data)) } } catch (ex) { // 状态码 awaitRes.statusCode = 404 // 找不到提示文本 awaitRes.end(`${filePath} is ${ex}`) } }
dir.js
修改
本节效果
close