首页 > 技术文章 > node 创建静态web服务器(上)

Sky-Ice 2018-07-30 11:14 原文

声明:本文仅用来做学习记录。

本文将使用node创建一个简单的静态web服务器。

准备工作:

首先,准备好一个类似图片中这样的页面

 

第一步:

创建 http 服务:

const http = require('http');  // 加载http服务模块

let server = http.createServer((req, res) => {
    res.writeHead(200, {'Content-Type': 'text/html;charset=utf-8'});
    res.end();   // 结束响应
})

server.listen(3000);  // 设置端口号

第二步:

获取 url , 我们要获取类似这样的url ,来展示对应的内容

http://localhost:3000/index.html
 let pathName = req.url;
 console.log(pathName);  // /index.html   /favicon.ico

这里,我们发现发送了两次请求,而 /favicon.ico 这个请求,我们是不需要的,所以,需要过滤掉。

同时,我们需要对空地址做处理,所以,代码如下:

  if (pathName == '/') {
      pathName = '/index.html';  // 如果请求地址为空,则加载首页
  }

  if (pathName != '/favicon.ico') {  // 当不请求 页面图标时
        
  }

接下来,我们需要读取服务器文件,首先加载 fs 模块

const fs = require('fs')

然后,如果请求的页面没有找到,则加载404页面:

if (pathName != '/favicon.ico') {  // 当不请求 页面图标时
        fs.readFile('static/' + pathName, (err, data) => {  // 读取对应文件
            if (err) {  // 如果没有找到文件
                fs.readFile('static/404.html', (err, data404) => {  // 则加载 404 页面
                    if (err) {
                        console.log('404');
                    } else {
                        res.writeHead(404, {'Content-Type': 'text/html;charset=utf-8'});  // 设置请求状态及表头
                        res.write(data404);  // 读取数据
                        res.end();   // 结束响应
                    }
                })
            }
        })
    return false;
}

找到则加载对应页面:

else {
        res.writeHead(200, {'Content-Type': 'text/html;charset=utf-8'});  // 设置请求状态及表头
        res.write(data);  // 读取数据
        res.end();   // 结束响应
    }

此时,我们已经可以看到效果如下:

但是,因为我们将所有请求的文件表头都设置为 

'Content-Type': 'text/html;charset=utf-8'

这显然是错误的做法,比如,css 文件, 我们应设置为 'text/css'  , js文件 , 设置为  'text/javascript' 。

下面,我们先创建一个文件夹,我将它命名为model,在该文件夹下创建一个js文件 getMime

代码如下:

const getMime = (extname) => {
    switch (extname) {
        case '.html':
            return 'text/html';
        case '.css':
            return 'text/css';
        case '.js':
            return 'text/javascript';
        default:
            return 'text/html';
    }
}
module.exports = {
    getMime
}

然后,加载该文件

const mimeModel = require('./model/getMime') // 加载getMime

我们要根据对应的请求的文件后缀名,来设置对应的文件格式,这里,我们需要引入 path模块

再用path.extname()方法,获取到对应的后缀名,

代码如下:

const http = require('http');  // 加载http服务模块
const fs = require('fs');      // 加载fs模块
const path = require('path');  // 加载path模块
const mimeModel = require('./model/getMime') // 加载getMime

let server = http.createServer((req, res) => {

    let pathName = req.url;
    console.log(pathName);

    if (pathName == '/') {
        pathName = '/index.html';  // 如果请求地址为空,则加载首页
    }
    let extName = path.extname(pathName);  // 获取请求文件的后缀名
    if (pathName != '/favicon.ico') {  // 当不请求 页面图标时
        fs.readFile('static/' + pathName, (err, data) => {  // 读取对应文件
            if (err) {  // 如果没有找到文件
                fs.readFile('static/404.html', (err, data404) => {  // 则加载 404 页面
                    if (err) {
                        console.log('404');
                    } else {
                        res.writeHead(404, {'Content-Type': 'text/html;charset=utf-8'});  // 设置请求状态及表头
                        res.write(data404);  // 读取数据
                        res.end();   // 结束响应
                    }
                })
                return false;
            } else {
                let mime = mimeModel.getMime(extName);  // 根据对应的后缀名,获取对应的文件格式
                res.writeHead(200, {'Content-Type': "" + mime + ";charset='utf-8'"});  // 设置请求状态及表头
                res.write(data);  // 读取数据
                res.end();   // 结束响应
            }
        })
    }

})

server.listen(3000);  // 设置端口号

 

结果如图所示:

 

但是,对应的图片并未加载进来,这是因为

 

这两个文件未加载,原因是请求地址后带参数,无法识别,所以,我们需要再引入url模块,使用url.parse()方法,将该地址解析为不带参数的地址

最后,完整代码如下:

const http = require('http');  // 加载http服务模块
const fs = require('fs');      // 加载fs模块
const path = require('path');  // 加载path模块
const url = require('url');    // 加载url模块
const mimeModel = require('./model/getMime') // 加载getMime

let server = http.createServer((req, res) => {

    let pathName = url.parse(req.url).pathname; // 解析请求地址不带参数
    console.log(pathName);

    if (pathName == '/') {
        pathName = '/index.html';  // 如果请求地址为空,则加载首页
    }
    let extName = path.extname(pathName);  // 获取请求文件的后缀名
    if (pathName != '/favicon.ico') {  // 当不请求 页面图标时
        fs.readFile('static/' + pathName, (err, data) => {  // 读取对应文件
            if (err) {  // 如果没有找到文件
                fs.readFile('static/404.html', (err, data404) => {  // 则加载 404 页面
                    if (err) {
                        console.log('404');
                    } else {
                        res.writeHead(404, {'Content-Type': 'text/html;charset=utf-8'});  // 设置请求状态及表头
                        res.write(data404);  // 读取数据
                        res.end();   // 结束响应
                    }
                })
                return false;
            } else {
                let mime = mimeModel.getMime(extName);  // 根据对应的后缀名,获取对应的文件格式
                res.writeHead(200, {'Content-Type': "" + mime + ";charset='utf-8'"});  // 设置请求状态及表头
                res.write(data);  // 读取数据
                res.end();   // 结束响应
            }
        })
    }

})

server.listen(3000);  // 设置端口号

结果如图:

但,此时,这个简单的静态web服务器只能识别 html,css,js 文件,比如图片的格式,也是 'text/html',这显然是不正确的,所以,仍需再做处理,下节再做介绍。

推荐阅读