http 模块

作者: 辉夜乀 | 来源:发表于2017-12-08 11:39 被阅读26次

    http 模块起一个本地服务器例子

    // 基础配置模块
    const defaultConfig = {
      hostname: '127.0.0.1',
      port: 9527
    };
    
    module.exports = defaultConfig;
    
    
    //创建服务器模块
    const http = require('http');
    const {port, hostname} = require('./config/defaultConfig');
    const chalk = require('chalk');
    
    const server = http.createServer((req, res) => {
      res.writeHead(200, {
        'Content-Type': "text/html; charset=utf8"
      });
      res.write('<h1>标题1</h1>');
      res.end();
    });
    
    server.listen(port, hostname, () => {
      let url = `http://${hostname}:${port}`;
      console.log(`打开浏览器,访问 ${chalk.green(url)}`);
    });
    
    

    supervisor

    每次修改 nodejs 文件都要重新执行一次 node 命令,用 supervisor 插件能 watch 所有文件的变化,一变化就自动帮我们执行 node 命令

    全局安装 supervisor

    npm i -g supervisor
    

    使用 supervisor 启动文件

    supervisor app.js
    

    anydoor 项目第一稿,回调版本

    const http = require('http');
    const path = require('path');
    const fs = require('fs');
    const {port, hostname, root} = require('./config/defaultConfig');
    const chalk = require('chalk');
    
    const server = http.createServer((req, res) => {
      /*获取用户的访问的 url*/
      let {url} = req;
      /*用根路径与用户访问的 url 拼接成绝对路径*/
      let filePath = path.join(root, url);
    
      /*判断是文件还是文件夹*/
      fs.stat(filePath, (err, stats) => {
        if (err) {
          res.writeHead(404, 'error', {
            'Content-Type': 'text/html; charset=utf8'
          });
          res.end(`${filePath} 不找到文件或文件夹`);
          return;
        }
        if (stats.isDirectory()) {
          /*如果是文件夹,则给出文件列表*/
          fs.readdir(filePath, (err, files) => {
            res.writeHead(200, 'directory', {
              'Content-Type': 'text/plain; charset=utf8'
            });
            res.end(files.join('\n'));
          });
        }
        if (stats.isFile()) {
          /*如果是文件,则返回文件内容*/
          res.writeHead(200, 'file', {
            'Content-Type': 'text/plain; charset=utf8'
          });
          fs.createReadStream(filePath).pipe(res);
        }
      });
    });
    
    server.listen(port, hostname, () => {
      let url = `http://${hostname}:${port}`;
      console.log(`打开浏览器,访问 ${chalk.green(url)}`);
    });
    
    

    anydoor 第二稿,async await 版

    我们用 promisify 模块来改造回调

    const http = require('http');
    const path = require('path');
    const fs = require('fs');
    const {port, hostname, root} = require('./config/defaultConfig');
    const chalk = require('chalk');
    const {promisify} = require('util');
    const stat = promisify(fs.stat);
    const readdir = promisify(fs.readdir);
    
    
    const server = http.createServer((req, res) => {
      /*获取用户的访问的 url*/
      let {url} = req;
      /*用根路径与用户访问的 url 拼接成绝对路径*/
      let filePath = path.join(root, url);
    
      route(res, filePath);
    });
    
    server.listen(port, hostname, () => {
      let url = `http://${hostname}:${port}`;
      console.log(`打开浏览器,访问 ${chalk.green(url)}`);
    });
    
    
    async function route(res, filePath) {
      try {
        const stats = await stat(filePath);
        /*判断是文件还是文件夹*/
        if (stats.isDirectory()) {
          /*如果是文件夹,则给出文件列表*/
    
          try {
            const files = await readdir(filePath);
            res.writeHead(200, 'directory', {
              'Content-Type': 'text/plain; charset=utf8'
            });
            res.end(files.join('\n'));
          }
    
          catch (err) {
            console.log(err);
          }
        }
        if (stats.isFile()) {
          /*如果是文件,则返回文件内容*/
          res.writeHead(200, 'file', {
            'Content-Type': 'text/plain; charset=utf8'
          });
          fs.createReadStream(filePath).pipe(res);
        }
    
      }
    
      catch (err) {
        res.writeHead(404, 'error', {
          'Content-Type': 'text/html; charset=utf8'
        });
        res.end(`${filePath} 不找到文件或文件夹`);
      }
    }
    
    

    anydoor 第三稿,用 handlebars 模板引擎将文件夹列表变成 html

    handlebars 文档

    • 安装 handlebars
    npm i --save handlebars
    
    • 创建一个模板 dir.hbs
    <!doctype html>
    <html lang="zh">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>{{title}}</title>
      <style>
        .directory {
          display: block;
          width: 200px;
          margin: 20px 0;
          background-color: #93fff8;
          text-decoration: none;
        }
      </style>
    </head>
    <body>
    {{#each files}}
      <a class="directory" href="{{../dir}}/{{this}}">{{this}}</a>
    {{/each}}
    </body>
    </html>
    
    • 创建一个渲染的数据
    let data = {
        title: path.basename(filePath), /*title 为文件名*/
        dir: dir ? `/${dir}` : '',      /*title 为文件所在的文件夹路径*/
        files                           /*files 是一个数组,为文件列表*/
    };
    
    • 引入 handlebars
    const Handlebars = require('handlebars');
    
    • 读取模板文件
        /*模板页面的路径*/
    const tplPath = path.join(__dirname, '../template/dir.hbs');
        
        /*读取模板内容,转成 utf8 的格式*/
    const source = fs.readFileSync(tplPath, 'utf8');
    
    • 使用 compile 方法生成一个模板
    const template = Handlebars.compile(source)
    
    • 渲染模板
    template(data)
    

    相关文章

      网友评论

        本文标题:http 模块

        本文链接:https://www.haomeiwen.com/subject/txheixtx.html