Node.js实现浏览本地文件(Demo)

985 阅读2分钟

如何实现浏览本地文件(根目录下包含多个子目录)?

核心步骤
const http = require('http');
const path = require('path');
const url = require('url');
const fs = require('fs');
const hostname = '127.0.0.1';
const port = 8010;

var documentRoot = 'F:/doc'; // 自定义本地文件根目录
var urls = [];  

const server = http.createServer((req,res)=>{
    let pathname = url.parse(req.url).pathname;
    var urlname = req.url;
    var file = documentRoot + urlname;
    console.log("第一个pathname:" + pathname); // 第一个pathname:/   附带:第一个pathname:/favicon.ico        点击server目录后(把/favicon.ico排除):第一个pathname:/server 
    console.log("urlname:" + urlname);// urlname:/    附带:urlname:/favicon.ico                            点击server目录后(把/favicon.ico排除):urlname:/server
    console.log("file:" + file);// file:D:/projects/node/lessons/servers/   附带:file:D:/projects/node/lessons/servers/favicon.ico            点击server目录后(把/favicon.ico排除):file:D:/projects/node/lessons/servers/server
    
    
    if(pathname == '/'){
        fs.readdir(documentRoot, function (err, files) {//异步方式读取文件目录,files2是一个包含 “指定目录下所有文件名称的” 数组
            if(err){
                console.log("files err");
                res.writeHeader(404,{
                    'content-type' : 'text/html;charset="utf-8"'
                });
                res.write('<h1>文件读取错误</h1><p>你要找的页面不存在</p>');
                res.end();
            }else{
                res.writeHeader(200,{
                    'content-type' : 'text/html;charset="utf-8"'
                });
                // urls=[];
                for (let i = 0; i < files.length; i++) {   
                    let filename = files[i];
                    fs.stat(filename,function(error,stats){
                        if(error){
                            res.write('<h1>分析文件错误</h1><p>你要找的页面不存在</p>');
                        }else{
                            //stats.isDirectory()判断给定的path是否是目录类型
                            if(stats.isDirectory()){
                                urls.push(filename);
                                res.write('<a href="'+ filename + '">'+ filename +'</a><br>');
                            }else{
                                res.write( files[i] +'<br>');  
                            }
                            if(i == files.length-1){
                                res.end();
                            }
                        }
                    });
                }
            }
        });
    }else if(pathname !== "/favicon.ico" && pathname !== "/"){
        //a链接显示
        //split() 方法用于把一个字符串分割成字符串数组,以'/'为界把路径名字符串切割为一个个字符串数组,[pathname.split("/").length-1]表示linkfilename只取最后的路径名
        let linkfilename = pathname.split("/")[pathname.split("/").length-1];
        console.log("linkfilename:" + linkfilename);//点击server目录后,linkfilename:server 每个目录都是单独显示,例如再点击server中asdasds,则显示linkfilename:asdasds
        let canRedirect = false;//Redirect是改变方向
        for (let j = 0; j < urls.length; j++) {//把urls中存放的文件目录循环出来,如果切割出来的linkfilename等于循环中的urls文件目录,则让canRedirect变为true,使得下面可以实现跳转返回上一级,同时打断和跳出循环,去执行下面的语句
            if(linkfilename == urls[j]){
                canRedirect = true;
                break;
            }
        }
        if(canRedirect){
            //要搜索到文件夹路径
            docRoot2 = documentRoot + pathname;
            console.log("可以跳转了");
            let backurl = "";
            
            for(let k=0; k < pathname.split("/").length-1; k++){
                backurl += "/" +  pathname.split("/")[k];
            }
            console.log("backurl222" + backurl);//结果为/  因为pathname:/server,从'/'开始分割,k=0, pathname.split("/")[k]为空值,backurl前面加/,若k=1时值为空,因为点击server目录,k < pathname.split("/").length-1;所以此循环无效直接跳出,backurl为空
            if(backurl == ""){
                backurl="/";
            }
            console.log("pathname:" + pathname);// /server  代表端口号后面所有的路径,你点击到哪个目录就显示到哪里
            console.log("docRoot2:" + docRoot2);// D:/projects/node/lessons/servers/server,说明已经进入了点击server后的目录页面
            console.log("backUrl:" + backurl);// /

            res.writeHeader(200, {'content-type': 'text/html;charset="utf-8"'});
            res.write('<a href="'+ backurl + '">../返回上一级</a><br>');
            fs.readdir(docRoot2, function (err, files2) {//异步方式读取文件目录,files2是一个包含 “指定目录下所有文件名称的” 数组
                if(err){
                    console.log("files err");
                    res.writeHeader(404,{
                        'content-type' : 'text/html;charset="utf-8"'
                    });
                    res.write('<h1>文件读取错误</h1><p>你要找的页面不存在</p>');
                    res.end();
                }else{
                    // urls=[];
                    console.log("子文件大小:" + files2.length);//files2是数组的形式显示
                    for (let m = 0; m < files2.length; m++) {   
                        let filename2 = files2[m];
                        let statfilename =  docRoot2 +"/" + files2[m];
                        let linkpathname2 = pathname + "/" + files2[m];
                        console.log(statfilename);// 点击server目录后      D:/projects/node/lessons/servers/server/a.html.txt   files2[0]=a.html.txt 
                        console.log(linkpathname2);// 点击server目录后     /server/a.html.txt
                        fs.stat(statfilename,function(error2,stats2){//获取文件信息
                            if(error2){
                                res.write('<h1>分析文件错误</h1><p>你要找的页面不存在</p>');
                            }else{
                                if (stats2.isDirectory()) {//stats.isDirectory()判断给定的path是否是目录类型
                                    urls.push(filename2);
                                    res.write('<a href="' + linkpathname2 + '">' + filename2 + '</a><br>');// 点击server目录后,若里面有目录,则可以跳转到linkpathname2为:  /server/目录名
                                }else{
                                    res.write( files2[m] +'<br>');  
                                }
                                if(m == files2.length-1){
                                    res.end();
                                }
                            }
                        });
                    }
                }
            });
            
        }else{
            console.log("错误了");
            res.writeHeader(404,{
                'content-type' : 'text/html;charset="utf-8"'
            });
            res.write('<h1>404错误</h1><p>你要找的页面不存在</p>');
            res.end();
        }
    }
});

server.listen(port,hostname,()=>{
    console.log(`Server running at  http://${hostname}:${port}/`);
})
实现效果