node学习-搭建简单的静态服务器

1.server 对象创建,通过http模块创建server对象,这里我们对请求的路径未做区分,只是单纯的返回当前的请求地址

let http = require('http');

class staticServer{
    constructor(){
        this.port = 8080;
    }

    useServer(){
        http.createServer((req,res)=>{
            res.end(`The current request address is : ${req.url}`)
        }).listen(this.port,()=>{
            console.log(`Server started on port ${this.port}`)
        })
    }
}

module.exports = staticServer;
当请求地址为:http://localhost:8080/index.html时,页面返回为:

2.下面我们对路径进行区分,即当请求对应的文件路径时,如果文件存在则返回对应的静态文件,如果请求静态文件不存在,那么返回"404"

    -  这里用的是流的形式createReadStream而不是readFile,是因为后者会在得到完整文件内容之前将其先读到内存里。这样万一文件很大,再遇上多个请求同时访问,readFile就承受不来了。使用文件可读流,服务端不用等到数据完全加载到内存再发回给客户端,而是一边读一边发送分块响应

class staticServer{
    constructor(){
        this.port = 8080;
        this.rootPath = './public';
    }

    // 404响应
    respondNotFound(pathname,res){
        res.statusCode = '404';
        res.end(`${pathname} is not found~~`);
    }

    // 用于返回文件的内容
    respondFile(filename,res){
        res.setHeader('Content-type','text/html');
        fs.createReadStream(filename).pipe(res);
    }

    useServer(){
        http.createServer((req,res)=>{
            let pathname = url.parse(req.url,true).pathname;
            let filename = this.rootPath+pathname;
            if (!fs.existsSync(filename)){
                this.respondNotFound(pathname,res);
            }else{
                this.respondFile(filename,res);
            }
        }).listen(this.port,()=>{
            console.log(`Server started on port ${this.port}`)
        })
    }
}

3.此时进行请求,我们通过响应头,看到不论是css亦或是图片的网络文件的类型都是"text/html",这是由于我们在respondFile函数中设置了"Content-type"一致为"text/html",这样就导致了除了text/html类型的文件无法正常查看

    - 为了解决上述的问题,需要对不同的文件类型设置不同的"Content-type",这里我们采用node自带的mime模块来响应不同文件类型的请求,更改respondFile函数如下:

// 用于返回文件的内容
respondFile(filename,res){
    res.setHeader('Content-type',`${mime.getType(filename)};charset=utf-8`);
    fs.createReadStream(filename).pipe(res);
}

     - 此时我们再看文件的"Content-type"就会是其文件对应的"Content-type":

    

4.在上面的代码中,我们请求的地址一直是某一个具体的文件,例如http://localhost:8080/index.html这样的url,如果我们请求的地址为http://localhost:8080,那么就会发生如下报错:


    - 为了解决这个问题,我们在对非文件进行请求时,即对目录文件进行请求时,默认返回请求目录下的index.html,如果index.html不存在的话,那么返回这个目录下的所有文件。首先我们先默认返回请求目录下的index.html

fs.stat(filename,(err,stats)=>{
    if (err) return console.log(err);
    if (stats.isFile()){     // 如果是文件的话,则返回文件内容
        this.respondFile(filename,res);
    }else if (stats.isDirectory()){   // 如果不是文件的话,则执行respondDirectory 
        this.reapondDiretory(filename,res);
    }
});
   reapondDiretory如下:
// 用于返回当路径为目录时的内容
reapondDiretory(filename,res){
    let p = filename+'index.html';
    if (fs.existsSync(p)){
        this.respondFile(p,res);
    }
}

    - 此时如果当前目录下并没有index.html的话,那么则返回目录下的所有 文件,代码如下:

// 用于返回当路径为目录时的内容
reapondDiretory(filename,res,req){
    let p = filename+'index.html';
    if (fs.existsSync(p)){
        this.respondFile(p,res);
    }else{
        fs.readdir(filename,(err,files)=>{
            if (err) return console.log(err);
            let str = '<ul>';
            files.forEach((file,index)=>{
                let itemLink = req.url+'/'+file;
                let stats = fs.statSync(path.join(filename,file));
                str += `<li><a href="${itemLink}">${itemLink}</a></li>`;
            });
            str += '</ul>';
            res.setHeader('Content-type','text/html;charset=utf-8');
            res.end(str);
        })
    }
}

5.以上就是使用node搭建的简单的静态服务器,完整代码如下:

let http = require('http');
let url = require('url');
let fs = require('fs');
let path = require('path');
let mime = require('mime');

class staticServer{
    constructor(){
        this.port = 8080;
        this.rootPath = './public';
    }

    // 404响应
    respondNotFound(pathname,res){
        res.statusCode = '404';
        res.end(`${pathname} is not found~~`);
    }
    // 用于返回文件的内容
    respondFile(filename,res){
        res.setHeader('Content-type',`${mime.getType(filename)};charset=utf-8`);
        let rs = fs.createReadStream(filename);
        rs.pipe(res);
    }
    // 用于返回当路径为目录时的内容
    reapondDiretory(filename,res,req){
        let p = filename+'index.html';
        if (fs.existsSync(p)){
            this.respondFile(p,res);
        }else{
            fs.readdir(filename,(err,files)=>{
                if (err) return console.log(err);
                let str = '<ul>';
                files.forEach((file,index)=>{
                    let itemLink = req.url+'/'+file;
                    let stats = fs.statSync(path.join(filename,file));
                    str += `<li><a href="${itemLink}">${itemLink}</a></li>`;
                });
                str += '</ul>';
                res.setHeader('Content-type','text/html;charset=utf-8');
                res.end(str);
            })
        }
    }

    useServer(){
        http.createServer((req,res)=>{
            let pathname = url.parse(req.url,true).pathname;
            let filename = this.rootPath+pathname;
            if (!fs.existsSync(filename)){
                this.respondNotFound(pathname,res);
            }else{
                fs.stat(filename,(err,stats)=>{
                    if (err) return console.log(err);
                    if (stats.isFile()){
                        this.respondFile(filename,res);
                    }else if (stats.isDirectory()){
                        this.reapondDiretory(filename,res,req);
                    }
                });
            }
        }).listen(this.port,()=>{
            console.log(`Server started on port ${this.port}`)
        })
    }
}

module.exports = staticServer;

文章参考:使用Node.js搭建静态资源服务器

猜你喜欢

转载自blog.csdn.net/qq_26443535/article/details/80117923