P12:node實現靜態服務器 ~ Content-Type優化設置

相關文章

縱觀代碼實現,咱們全部的MIME類型只有兩種,這時候會出現一個問題,項目中從出現圖片,視頻文本文件,就不會輸出給咱們正確的Content-Type。雖然大多數高級瀏覽器仍是會在設置錯誤的狀況下依輸出正確。可是這並不能成爲咱們忽視這一項配置的緣由。在接口調用或者其餘使用中,咱們常常活判斷Content-Type類型,以此作出相應的響應。javascript

爲了嚴謹,解決它!解決它!解決它!css

文件類型 Content-Type

Content-Type:便是Internet MediaType,互聯網媒體類型,也叫作MIME類型。 用於定義網絡文件的類型和網頁的編碼,決定瀏覽器將以什麼形式、什麼編碼讀取這個文件html

  • 咱們出於學習得目的在此貼出一個經常使用的MIME類型對應關係。類型不全,商業項目慎用java

    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,可是總去瀏覽器後臺查看也太蠢了,須要對文件作頁面內標識node

  • 爲了方便查看貼出文件所有代碼 route.jsjson

    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數組

相關文章
相關標籤/搜索