美文网首页
Node.js学习——利用 HTTP、Url、Path、Fs 模

Node.js学习——利用 HTTP、Url、Path、Fs 模

作者: wxyzcctn | 来源:发表于2022-01-24 09:56 被阅读0次

    实验操作

    新建一个app.js文件

    const http = require('http');
    const fs = require('fs');
    const path = require('path');
    const url = require('url');
    
    let common = require('./modules/common');
    
    http.createServer((req, res) => {
    
        let pathName = req.url; // 获取到请求的url
    
        pathName = url.parse(pathName).pathname; // 使用url内置模块获取路径名
        pathName = pathName !== '/' ? pathName : '/index.html' // 获取到/就默认为/index.html
    
        let extname = path.extname(pathName);  // 使用内部模块path获取文件后缀名
    
        if (pathName !== "/favicon.ico") {
            fs.readFile(path.join(__dirname, '../static') + pathName, (err, data) => {
                // 使用path根据当前路劲获得读取文件的相对路径
                if (err) {
                    res.writeHead(404, {
                        "Content-Type": "text/html;charset=UTF-8"
                    });
                    res.end('404这个网页不存在');
                }
                let mime = common.getMime(extname);  // 使用自定义模块根据后缀名获取Content-Type的值
    
                res.writeHead(200, {
                    "Content-Type": "" + mime + ";charset=UTF-8"
                });
                res.end(data);
            })
        }
    
    }).listen(3000);
    
    console.log("Server runing at http://127.0.0.1:3000");
    

    在app.js目录下新建/modules/common.js

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

    以上的common.js中的getMime 函数所列举的类并不完整,引入完整的对应关系需要使用一个json文件:https://github.com/wxyzcctv/node-demo-sd10/blob/main/data/mime.json
    该json文件放在/data/mime.json
    在common.js文件中使用添加如下代码:

    const fs = require('fs');
    const path = require('path');
    // 方式一
    exports.getFileMime = function (extname) {
        return new Promise((resolve, reject) => {
            fs.readFile(path.join(__dirname, '../data/mime.json'), (err, data) => {
                if (err) {
                    console.log(err);
                    reject(err)
                    return err;
                }
                let mime = JSON.parse(data.toString());
                resolve(mime[extname])
            })
        })
    }
    
    // 方式二:
    exports.getFileMime = function (extname) {
        let data = fs.readFileSync(path.join(__dirname, '../data/mime.json'));
        let mime = JSON.parse(data.toString());
        return mime[extname]
    }
    

    common.js中使用方式一,此时app.js中代码为

    const http = require('http');
    const fs = require('fs');
    const path = require('path');
    const url = require('url');
    
    let common = require('./modules/common');
    
    http.createServer((req, res) => {
    
        let pathName = req.url; // 获取到请求的url
    
        pathName = url.parse(pathName).pathname; // 使用url内置模块获取路径名
        pathName = pathName !== '/' ? pathName : '/index.html' // 获取到/就默认为/index.html
    
        let extname = path.extname(pathName);  // 使用内容模块path获取文件后缀名
    
        if (pathName !== "/favicon.ico") {
            fs.readFile(path.join(__dirname, './static') + pathName, async (err, data) => {
                // 使用path根据当前路劲获得读取文件的相对路径
                if (err) {
                    res.writeHead(404, {
                        "Content-Type": "text/html;charset=UTF-8"
                    });
                    res.end('404这个网页不存在');
                }
                // let mime = common.getMime(extname);  // 使用自定义模块根据后缀名获取Content-Type的值
                let mime = await common.getFileMime(extname);  // 使用自定义模块根据后缀名获取Content-Type的值
    
                res.writeHead(200, {
                    "Content-Type": "" + mime + ";charset=UTF-8"
                });
                res.end(data);
            })
        }
    
    }).listen(3000);
    
    console.log("Server runing at http://127.0.0.1:3000");
    

    common.js中使用方式二就在app.js中就去掉async和await

    封装静态web服务

    新建/module/routers.js

    const fs = require('fs');
    const path = require('path');
    const url = require('url');
    
    let getFileMime = function (extraname) {
        let data = fs.readFileSync(path.join(__dirname,'../data/mime.json'));  // 同步操作
        data = JSON.parse(data.toString())
        return data[extraname]
    }
    
    exports.static = function(req,res,staticPath){
    
        let pathName = req.url; // 获取到请求的url
        
        pathName = url.parse(pathName).pathname; // 使用url内置模块获取路径名
        pathName = pathName !== '/' ? pathName : '/index.html' // 获取到/就默认为/index.html
    
        let extname = path.extname(pathName);  // 使用内容模块path获取文件后缀名
        
        if (pathName !== "/favicon.ico") {
    
            try {
                let data = fs.readFileSync('../' + staticPath + pathName);  // 同步操作
    
                if(data){
                    let mime = getFileMime(extname);  // 使用自定义模块根据后缀名获取Content-Type的值
    
                    res.writeHead(200, {
                        "Content-Type": "" + mime + ";charset=UTF-8"
                    });
                    res.end(data);
                }
            } catch (error) {
                
            }        
        }
    }
    

    在app.js文件中

    const http = require('http');
    
    const url = require('url');
    
    let routers = require('./modules/routers.js');
    
    
    http.createServer((req, res) => {
    
    
        routers.static(req, res, 'static');
        // 增加路由
        let pathName = url.parse(req.url).pathname;
        if(pathName === '/login'){
            res.writeHead(200, {
                "Content-Type": "text/html;charset=UTF-8"
            });
            res.end('访问登录页面');
        } else if(pathName === '/register'){
            res.writeHead(200, {
                "Content-Type": "text/html;charset=UTF-8"
            });
            res.end('访问登录页面');
        } else if(pathName === '/admin'){
            res.writeHead(200, {
                "Content-Type": "text/html;charset=UTF-8"
            });
            res.end('访问管理页面');
        }
    
    }).listen(3000);
    
    console.log("Server runing at http://127.0.0.1:3000");
    

    使用ejs

    EJS 常用标签

    <% %>流程控制标签
    <%= %>输出标签(原文输出 HTML 标签)
    <%- %>输出标签(HTML 会被浏览器解析)
    
    <a href="<%= url %>"><img src="<%= imageURL %>" alt=""></a><ul>
    <ul> <% for(var i = 0 ; i < news.length ; i++){ %> <li><%= news[i] %></li> <% } %> </ul>
    

    先安装ejs: npm install ejs --save
    新建views/login.ejs文件

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    
    <body>
        <h2>这是一个登录页面</h2>
        <h3>
            <%=msg%>
        </h3>
    
        <br>
    
        <ul>
            <%for(let i=0; i < list.length; i++){ %>
                <li>
                    <%=list[i].title%>
                </li>
                <%}%>
    
        </ul>
    </body>
    
    </html>
    

    然后在app.js中使用ejs

    const http = require('http');
    const url = require('url');
    let routes = require('./modules/routes');
    const ejs = require('ejs')
    
    
    http.createServer((req, res) => {
    
        routes.static(req, res, 'static')
    
        let pathName = url.parse(req.url).pathname;
        if (pathName === '/login') {
            let msg = "这是数据库传回的数据";
            let list = [
                { title: '标题1' },
                { title: '标题2' },
                { title: '标题3' },
                { title: '标题4' },
                { title: '标题5' },
            ]
            ejs.renderFile('./views/login.ejs', { msg: msg, list: list }, (err, data) => {
                if (err) {
                    console.log(err);
                    return;
                }
                res.writeHead(200, {
                    "Content-Type": "text/html;charset=UTF-8"
                });
                res.end(data)
            })
        } else if (pathName === '/register') {
            res.writeHead(200, {
                "Content-Type": "text/html;charset=UTF-8"
            });
            res.end('正在操作注册页面')
        } else if (pathName === '/admin') {
            res.writeHead(200, {
                "Content-Type": "text/html;charset=UTF-8"
            });
            res.end('处理之后的业务逻辑')
        } else {
            // res.writeHead(404, {
            //     "Content-Type": "text/html;charset=UTF-8"
            // });
            // res.end('404页面不存在')
        }
    
    }).listen(3000);
    
    console.log("Server runing at http://127.0.0.1:3000");
    

    获取请求方法名
    req.method;

    GET请求

    获取 GET 传值:
    var urlinfo=url.parse(req.url,true).query;
    在app.js中添加/news的路由,并在浏览器的地址栏中输入http://localhost:3000/news?id=1&page=2实现get请求,

    const http = require('http');
    const url = require('url');
    let routes = require('./modules/routes');
    const ejs = require('ejs')
    
    http.createServer((req, res) => {
        routes.static(req, res, 'static')
    
        let pathName = url.parse(req.url).pathname;
        if (pathName === '/login') {
            res.writeHead(200, {
                "Content-Type": "text/html;charset=UTF-8"
            });
            res.end('这是一个登录页面')
        } else if (pathName === '/register') {
            res.writeHead(200, {
                "Content-Type": "text/html;charset=UTF-8"
            });
            res.end('正在操作注册页面')
        } else if (pathName === '/admin') {
            res.writeHead(200, {
                "Content-Type": "text/html;charset=UTF-8"
            });
            res.end('处理之后的业务逻辑')
        } else if (pathName === '/news') {
            // 获取请求方法名
            console.log(req.method);
            let params = url.parse(req.url, true).query;
            console.log(params.page);
            res.writeHead(200, {
                "Content-Type": "text/html;charset=UTF-8"
            });
            res.end('获取get请求成功')
        }
    
    }).listen(3000);
    
    console.log("Server runing at http://127.0.0.1:3000");
    

    POST请求

    获取 POST 传值:

    var postData = ''; 
    // 数据块接收中 
    req.on('data', function (postDataChunk) {
        postData += postDataChunk;
    });
     // 数据接收完毕,执行回调函数 
    req.on('end', function () {
        try {
            postData = JSON.parse(postData);
        } catch (e) {}
        req.query = postData;
        console.log(querystring.parse(postData));
    });
    

    新建views/form.ejs

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    
    <body>
        <form action="/doLogin" method="post">
            用户名:<input type="text" name="userName" value="admin">
            <br>
            <br>
            密 码:<input type="password" name="password" value="123456">
            <br>
            <br>
            <input type="submit" value="提交">
    
        </form>
    </body>
    
    </html>
    

    在app.js中修改logoin路由中的内容并以及新增一个/doLogin路由

    if (pathName === '/login') {
            ejs.renderFile('./views/form.ejs', (err, data) => {
                if (err) {
                    console.log(err);
                    return err;
                }
                res.writeHead(200, {
                    "Content-Type": "text/html;charset=UTF-8"
                });
                res.end(data)
            })
        } else if (pathName === '/doLogin') {
            let postStr = '';
            req.on('data', (chunk) => {
                postStr += chunk
            })
            req.on('end', () => {
                console.log(postStr);
                res.end(postStr)
            })
        }
    

    封装路由

    在/modules/routers.js文件中
    使用app对象封装静态方法和路由访问

    const fs = require('fs');
    const path = require('path');
    const url = require('url');
    const ejs = require('ejs');
    
    let getFileMime = function (extraname) {
        let data = fs.readFileSync(path.join(__dirname,'../data/mime.json'));
        data = JSON.parse(data.toString())
        return data[extraname]
    }
    
    let app = {
        static: function(req,res,staticPath){
            let pathName = req.url; // 获取到请求的url
            pathName = url.parse(pathName).pathname; // 使用url内置模块获取路径名
            pathName = pathName !== '/' ? pathName : '/index.html' // 获取到/就默认为/index.html    
            let extname = path.extname(pathName);  // 使用内容模块path获取文件后缀名        
            if (pathName !== "/favicon.ico") {
                try {
                    let data = fs.readFileSync('./' + staticPath + pathName);
                    if(data){
                        let mime = getFileMime(extname);  // 使用自定义模块根据后缀名获取Content-Type的值    
                        res.writeHead(200, {
                            "Content-Type": "" + mime + ";charset=UTF-8"
                        });
                        res.end(data);
                    }
                } catch (error) {
                    
                }            
            }
        },
        // 该部分是路由封装
        // <-----------
        login: (req,res)=>{
            // 处理登录路由的操作
            ejs.renderFile(path.join(__dirname,'../views/form.ejs'),(err,data)=>{
                if(err){
                    console.log(err);
                    return err;
                }
                res.writeHead(200, {
                    "Content-Type": "text/html;charset=UTF-8"
                });
                res.end(data);
            })
        },
        register: (req,res)=>{
            // 处理注册路由的操作
            res.writeHead(200, {
                "Content-Type": "text/html;charset=UTF-8"
            });
            res.end('访问注册页面');
        },
        admin: (req,res)=>{
            // 处理操作路由的操作
            res.writeHead(200, {
                "Content-Type": "text/html;charset=UTF-8"
            });
            res.end('访问操作页面');
        },
        doLogin: (req,res)=>{
            // 处理返回的post请求路由
            let postStr = ''
            req.on('data',(chunk)=>{
                postStr += chunk;
            });
            req.on('end', ()=>{
                console.log(postStr);
                res.end(postStr)
            })
        },
        error: (req,res)=>{
            // 处理不存在的路由
            res.writeHead(404, {
                "Content-Type": "text/html;charset=UTF-8"
            });
            res.end('访问页面不存在');
        },
        // ----------->
    }
    
    module.exports = app;
    

    此时的app.js修改为如下内容

    const http = require('http');
    const url = require('url');
    let routers = require('./modules/routers.js');
    
    http.createServer((req, res) => {
    
        routers.static(req, res, 'static');
        // 获取路由名称
        let pathName = url.parse(req.url).pathname.replace('/','');
        try {
            routers[pathName](req,res);
        } catch (error) {
            routers['error'](req,res);
        }    
    
    }).listen(3000);
    
    console.log("Server runing at http://127.0.0.1:3000");
    

    相关文章

      网友评论

          本文标题:Node.js学习——利用 HTTP、Url、Path、Fs 模

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