ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Node.js 写一个简单的静态服务器 5 MIME

2019-04-26 14:50:11  阅读:271  来源: 互联网

标签:Node fs const filePath res require js MIME path


MIME - Multipurpose Internet Mail Extensions , 它是描述消息内容的类型的因特网标准。

http://www.w3school.com.cn/media/media_mimeref.asp

我们之前在代码中设置的“Content-Type”, 为 "text/plain" 与 "text/html" 。就是设置两种不同的MIME 。

我们常用的还有 “application/javascript” (javascript), "image/png"(png), "image/jpeg" 。

浏览器可以根据Content-Type 来解析传递过来的数据。

之前的代码里,我们是直接指定,res 的Content-Type 为一个字符串的。下面我们在一个模块里统一定一下MIME,然后在需要的地方引入。

我们在 src/helper 下新建一个文件 mime.js , 在mime.js 里面定义好mime 类型,然后export 一个方法根据扩展名返回MIME 类型。如下。

const path = require('path');

const mimeType = {
    'css': 'text/css',
    'gif': 'image/gif',
    'html': 'text/html',
    'ico': 'image/x-icon',
    'jpeg': 'imag/jpeg',
    'jpg': 'image/jpeg',
    'json': 'application/json',
    'js': 'text/javascript',
    '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'
}

module.exports = (filePath) => {
    let ext = path.extname(filePath).split('.').pop().toLowerCase();
    if(!ext) {
        ext = filePath;
    }
    return mimeType[ext] || mimeType['txt'];
}

好,然后,我们去使用MIME 的地方去试一试。src/helper 下的 route.js 。如下。

const fs = require('fs');
const path = require('path');
const ejs = require('ejs');
const promisify = require('util').promisify;
const conf = require('../config/defaultConfig');
const mime = require('./mime');

const stat = promisify(fs.stat);
const readdir = promisify(fs.readdir);

const ejsPath = path.join(__dirname, '../templates/main-page.ejs');
const source = fs.readFileSync(ejsPath,'utf-8');

module.exports = async function (req, res, filePath) {
    try {
        const stats = await stat(filePath);
        if (stats.isFile()) {
          const contentType = mime(filePath);
          res.statusCode = 200;
          res.setHeader('Content-Type', contentType);
          fs.createReadStream(filePath).pipe(res)
        }
        if (stats.isDirectory()) {
          const files = await readdir(filePath);
          res.statusCode = 200;
          res.setHeader('Content-Type', 'text/html');
          const dir = path.relative(conf.root, filePath)
          const data = {
            title: path.basename(filePath),
            dir: dir ? `/${dir}` : '',
            files
          };
          res.end(ejs.render(source, data));
        }
      } catch(ex) {
        res.statusCode = 404;
        res.setHeader('Content-Type', 'text/plain');
        res.end(`${filePath} is not a file or directory`);
      }
}

为了美观,我们可以为每个file 添加一个图标。在route.js 中可以这样写。

const fs = require('fs');
const path = require('path');
const ejs = require('ejs');
const promisify = require('util').promisify;
const conf = require('../config/defaultConfig');
const mime = require('./mime');

const stat = promisify(fs.stat);
const readdir = promisify(fs.readdir);

const ejsPath = path.join(__dirname, '../templates/main-page.ejs');
const source = fs.readFileSync(ejsPath,'utf-8');

module.exports = async function (req, res, filePath) {
    try {
        const stats = await stat(filePath);
        if (stats.isFile()) {
          const contentType = mime(filePath);
          res.statusCode = 200;
          res.setHeader('Content-Type', contentType);
          fs.createReadStream(filePath).pipe(res)
        }
        if (stats.isDirectory()) {
          const files = await readdir(filePath);
          res.statusCode = 200;
          res.setHeader('Content-Type', 'text/html');
          const dir = path.relative(conf.root, filePath)
          const data = {
            title: path.basename(filePath),
            dir: dir ? `/${dir}` : '',
            files: files.map((file) => {
              return {
                file,
                icon: mime(file)
              }
            })
          };
          res.end(ejs.render(source, data));
        }
      } catch(ex) {
        res.statusCode = 404;
        res.setHeader('Content-Type', 'text/plain');
        res.end(`${filePath} is not a file or directory`);
      }
}

然后,我们去改一下模板,如下。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        body {
            margin: 30px;
        }
        a {
            display: block;
            font-size: 15px;
        }
    </style>
</head>
<body>
    <% files.map( file => { %>
        <a href="<%= dir %>/<%= file %>"> [<%= file.icon %>] <%= file.file %> </a>
    <% }) %>
</body>
</html>

当然,可以根据icon 添加小图标的,就不演示了。

标签:Node,fs,const,filePath,res,require,js,MIME,path
来源: https://blog.csdn.net/purple_lumpy/article/details/89532148

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有