P12:node实现静态服务器 ~ Content-Type优化设置

2,124 阅读3分钟

相关文章

纵观代码实现,我们所有的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