node.js入门学习(四)--Demo

需求:图书的增删改查,图书数据保存在data.json文件中。

1、Demo结构:

  

2、首先下载安装node.js,配置环境变量:参考博客

3、项目初始化

  1)创建项目根目录node-hello,进入到根目录node-hello,右键/在此处打开PowerShell窗口。

  2)创建app.js文件。

  3)在控制台输入命令:npm init -y,会自动创建package.json文件。

  4)在控制台输入命令:npm install mime,会自动创建node_modules文件夹,并下载mime模块到该文件夹,还会自动生成package-lock.json文件。

  5)npm install underscore,下载underscore模块。underscore的使用参考博客

4、入口文件app.js

// 加载http模块
var http = require("http");
var fs = require("fs");
var path = require("path");
var mime = require("mime");
var url = require("url");
var querystring = require("querystring");
var _ = require("underscore");

// 创建一个http服务对象
http.createServer(function(req, res) {

    req.url = req.url.toLowerCase();
    req.method = req.method.toLowerCase();
    if (req.method === ‘get‘) {
        // 通过url模块的parse方法获取用户get请求提交的数据
        // 第二个参数为true时,urlObj的query属性就是所有的请求参数,类型是json对象
        var urlObj = url.parse(req.url, true);
        // console.log(urlObj);
    } 

    // 封装fender函数,将render函数挂在到res对象上;第二个参数是模板数据
    res.render = function (filename, templateData) {
        fs.readFile(filename, function(err, data) {
            if(err) {
                res.writeHead(404, ‘not found‘, {‘Content-Type‘: ‘text/html; charset=utf-8‘});
                res.end("404, not found.");
                return;
            }

            if (templateData) {
                var fn = _.template(data.toString("utf-8"));
                data = fn(templateData);
            }

            res.setHeader(‘Content-Type‘, mime.getType(filename));
            res.end(data);
        });
    };

    if(req.url === ‘/‘ || req.url === ‘/index‘) {
        res.render(path.join(__dirname, ‘pages/index.html‘));
    }
    else if(req.url === ‘/list‘) {
        // 第一步:读取data.json文件中的数据,转换为list数组
        fs.readFile(path.join(__dirname, ‘data‘, ‘data.json‘), ‘utf-8‘, function (err, data) {
            if(err && err.code !== ‘ENOENT‘) {throw err;}
            console.log("data.json原来的内容:" + data); // [{"name":"xxx","price":"xxx"}]]
            var bookList = JSON.parse(data || ‘[]‘); // json数组

            // 第二步:在服务器使用模版引擎,将bookList数据和list.html页面结合
            res.render(path.join(__dirname, ‘pages/list.html‘), {msg:‘这是list页面‘, bookList:bookList});
        });
    }
    else if(req.url.startsWith(‘/add‘)) {
        res.render(path.join(__dirname, ‘pages/add.html‘));
    }
    else if(req.url.startsWith(‘/submit‘) && req.method === ‘get‘) { // 如何获取get请求的参数
        // 用户表单提交get请求数据,保存到data/data.json文件中,新数据以追加的形式添加
        console.log(req.url); // /summit?name=xxx&price=xxx

        // 首先读取data.json文件的内容
        fs.readFile(path.join(__dirname, ‘data‘, ‘data.json‘), ‘utf-8‘, function (err, data) {
            if(err && err.code !== ‘ENOENT‘) {throw err;}
            console.log("data.json原来的内容:" + data); // [{"name":"xxx","price":"xxx"}]]
            var list = JSON.parse(data || ‘[]‘); // json数组

            // 获取get请求的参数,将用户提交的数据添加到json数组
            var book = urlObj.query;
            // book.id = list.length + 1;
            book.id = list[list.length - 1].id + 1;
            list.push(book);
            console.log("添加一条记录后,data.json的内容:"  + JSON.stringify(list));

            // 将json数组写入data.json文件
            fs.writeFile(path.join(__dirname, ‘data‘, ‘data.json‘), JSON.stringify(list), function(err) {
                if(err) throw err;
                console.log(‘写入成功‘);
            });
        });

        // 重定向
        res.statusCode = 302;
        res.statusMessage = ‘Found‘;
        res.setHeader(‘Location‘, ‘/index‘);
        res.end();
    }
    else if(req.url.startsWith(‘/submit‘) && req.method === ‘post‘) { // 如何获取post请求的参数
        var array = []; // 用来保存用户post请求提交的数据
        var postBody;
        req.on(‘data‘, function(chunk) {
            // chunk就是浏览器本次data事件提交的一部分数据;chunk是Buffer类型
            console.log("data事件...");
            array.push(chunk);
        });

        req.on(‘end‘, function() {
            console.log("end事件...");
            // 把array中多个Buffer对象汇总到一个Buffer对象
            postBody = Buffer.concat(array);
            console.log("postBody: " + postBody); // postBody: name=1&price=1
        });

        fs.readFile(path.join(__dirname, ‘data‘, ‘data.json‘), ‘utf-8‘, function (err, data) {
            if(err && err.code !== ‘ENOENT‘) {throw err;}
            console.log("data.json原来的内容:" + data); // [{"name":"xxx","price":"xxx"}]]
            var list = JSON.parse(data || ‘[]‘); // json数组

            // 获取get请求的参数,将用户提交的数据添加到json数组
            // querystring对象可以把表单数据 name=xxx&price=xxx => {"name":"xxx","price":"xxx"}
            var book = querystring.parse(postBody.toString("utf-8"));
            // book.id = list.length + 1;
            book.id = list[list.length - 1].id + 1;
            list.push(book);
            console.log("添加一条记录后,data.json的内容:"  + JSON.stringify(list));

            // 将json数组写入data.json文件
            fs.writeFile(path.join(__dirname, ‘data‘, ‘data.json‘), JSON.stringify(list), function(err) {
                if(err) throw err;
                console.log(‘写入成功‘);
            });
        });

        /*
        // 首先读取data.json文件的内容
        fs.readFile(path.join(__dirname, ‘data‘, ‘data.json‘), ‘utf-8‘, function (err, data) {
            if(err && err.code !== ‘ENOENT‘) {throw err;}
            console.log("data.json原来的内容:" + data); // [{"name":"xxx","price":"xxx"}]]
            var list = JSON.parse(data || ‘[]‘); // json数组

            // 获取post请求的参数,将用户提交的数据添加到json数组
            // 因为post提交数据的时候,数据量可能比较大,所以可能分多次提交,每次添加一部分数据
            // 此时服务器要获取用户提交的所有数据,必须监听request对象的data事件
            // 什么时候表示浏览器把所有数据都提交到服务器了呢?当request对象的end事件触发
            var array = []; // 用来保存用户post请求提交的数据
            console.log("111...");
            req.on(‘data‘, function(chunk) {
                // chunk就是浏览器本次data事件提交的一部分数据;chunk是Buffer类型
                console.log("data事件...");
                array.push(chunk);
            });
            req.on(‘end‘, function() {
                console.log("end事件...");
                // 把array中多个Buffer对象汇总到一个Buffer对象
                var postBody = Buffer.concat(array);
                console.log("postBody: " + postBody);
                list.push(postBody);
                console.log("添加一条记录后,data.json的内容:"  + JSON.stringify(list));

                // 将json数组写入data.json文件
                fs.writeFile(path.join(__dirname, ‘data‘, ‘data.json‘), JSON.stringify(list), function(err) {
                    if(err) throw err;
                    console.log(‘写入成功‘);
                });
            });

            console.log("222...");
        });*/

        // 重定向
        res.statusCode = 302;
        res.statusMessage = ‘Found‘;
        res.setHeader(‘Location‘, ‘/index‘);
        res.end();
    }
    else if(req.url.startsWith(‘/detail‘) && req.method === ‘get‘) {
        var queryId = urlObj.query.id;

        // 第一步:读取data.json文件中的数据,转换为list数组
        fs.readFile(path.join(__dirname, ‘data‘, ‘data.json‘), ‘utf-8‘, function (err, data) {
            if(err && err.code !== ‘ENOENT‘) {throw err;}
            console.log("data.json原来的内容:" + data); // [{"name":"xxx","price":"xxx"}]]
            var bookList = JSON.parse(data || ‘[]‘); // json数组

            // 查询指定id的记录
            var book = {};
            for (var i = 0; i < bookList.length; i++) {
                if (bookList[i].id == queryId) { // 不能写“===”,因为queryId是字符串类型
                    book = bookList[i];
                }
            }

            // 第二步:在服务器使用模版引擎,将数据和detail.html页面结合
            res.render(path.join(__dirname, ‘pages/detail.html‘), {book:book});
        });
    }
    else if(req.url.startsWith(‘/delete‘) && req.method === ‘get‘) {
        var queryId = urlObj.query.id;

        // 第一步:读取data.json文件中的数据,转换为list数组
        fs.readFile(path.join(__dirname, ‘data‘, ‘data.json‘), ‘utf-8‘, function (err, data) {
            if(err && err.code !== ‘ENOENT‘) {throw err;}
            console.log("data.json原来的内容:" + data); // [{"name":"xxx","price":"xxx"}]]
            var bookList = JSON.parse(data || ‘[]‘); // json数组

            // 删除指定id的记录
            for (var i = 0; i < bookList.length; i++) {
                if (bookList[i].id == queryId) {
                    bookList.splice(i, 1); // 删除起始下标为queryId-1,长度为1的元素
                }
            }

            // 将json数组重新写入data.json文件
            fs.writeFile(path.join(__dirname, ‘data‘, ‘data.json‘), JSON.stringify(bookList), function(err) {
                if(err) throw err;
                console.log(‘写入成功‘);
            });    

            // 第二步:在服务器使用模版引擎,将bookList数据和list.html页面结合
            res.render(path.join(__dirname, ‘pages/list.html‘), {msg:‘这是list页面‘, bookList:bookList});
        });
    }
    else if(req.url.includes(‘static‘)){
        res.render(path.join(__dirname, req.url));
    }
    else if(req.url.startsWith(‘/edit‘) && req.method === ‘post‘) {
        var array = []; // 用来保存用户post请求提交的数据
        var postBody;
        req.on(‘data‘, function(chunk) {
            // chunk就是浏览器本次data事件提交的一部分数据;chunk是Buffer类型
            console.log("data事件...");
            array.push(chunk);
        });

        req.on(‘end‘, function() {
            console.log("end事件...");
            // 把array中多个Buffer对象汇总到一个Buffer对象
            postBody = Buffer.concat(array);
        });

        fs.readFile(path.join(__dirname, ‘data‘, ‘data.json‘), ‘utf-8‘, function (err, data) {
            if(err && err.code !== ‘ENOENT‘) {throw err;}

            var bookList = JSON.parse(data || ‘[]‘); // json数组

            // 获取get请求的参数,将用户提交的数据添加到json数组
            // querystring对象可以把表单数据 name=xxx&price=xxx => {"name":"xxx","price":"xxx"}
            var book = querystring.parse(postBody.toString("utf-8"));
            console.log("=============book:" + book.id + book.name + book.price);
            for (var i = 0; i < bookList.length; i++) {
                // console.log("bookList[i].id=" + bookList[i].id);
                // console.log("book.id=" + book.id);
                // console.log(bookList[i].id == book.id);
                if(bookList[i].id == book.id) {
                    bookList[i].name = book.name;
                    bookList[i].price = book.price;
                }
            }

            // 将json数组重新写入data.json文件
            fs.writeFile(path.join(__dirname, ‘data‘, ‘data.json‘), JSON.stringify(bookList), function(err) {
                if(err) throw err;
                console.log(‘写入成功‘);
            });    

            // 重定向
            res.statusCode = 302;
            res.statusMessage = ‘Found‘;
            res.setHeader(‘Location‘, ‘/list‘);
            res.end();
            });
    }
    else {
        res.writeHead(404, ‘not found‘, {‘Content-Type‘: ‘text/html; charset=utf-8‘});
        res.end("404,not found!");
    }
}).listen(‘8080‘, function() {
    console.log(‘服务器已经启动,请访问http://127.0.0.1:8080/‘);
});

5、common.css

h2 {
    background-color: #ccc;
}

6、html页面

  add.html

<!DOCTYPE html>
<html>
<head>
    <title>add页面</title>
    <meta charset="utf-8">
    <link rel="stylesheet" type="text/css" href="/static/css/common.css">
</head>
<body>
    <h2>add页面</h2>
    <form method="get" action="/submit">
    <!-- <form method="post" action="/submit"> -->
        书名: <input type="text" name="name">
        价格: <input type="text" name="price">
        <input type="submit" value="添加">
    </form>
</body>
</html>

  detail.html

<!DOCTYPE html>
<html>
<head>
    <title>detail页面</title>
    <meta charset="utf-8">
    <link rel="stylesheet" type="text/css" href="/static/css/common.css">
</head>
<body>
    <h2>detail页面</h2>
    <form method="post" action="/edit">
        <input type="hidden" name="id" value="<%= book.id %>">
        书名:<input type="text" name="name" value="<%= book.name %>"><br/>
        价格:<input type="text" name="price" value="<%= book.price %>"><br/>
        <input type="submit" value="修改">
    </form>
</body>
</html>

  index.html

<!DOCTYPE html>
<html>
<head>
    <title>index页面</title>
    <meta charset="utf-8">
    <link rel="stylesheet" type="text/css" href="/static/css/common.css">
</head>
<body>
    <h2>index页面</h2>
    <!-- <img src="/static/images/1.jpg">
    <img src="/static/images/2.png"> -->
    <a href="/list">图书列表</a>
</body>
</html>

  list.html

<!DOCTYPE html>
<!DOCTYPE html>
<html>
<head>
    <title>list页面</title>
    <meta charset="utf-8">
    <link rel="stylesheet" type="text/css" href="/static/css/common.css">
</head>
<body>
    <h2>list页面</h2>
    <%= msg %>!</h2><br/>
    <!-- <img src="/static/images/1.jpg">
    <img src="/static/images/2.png"> -->
    <a href="/add">添加</a>

    <table border="1" cellpadding="0">
        <tr>
            <td>ID</td>
            <td>书名</td>
            <td>价格</td>
            <td>操作</td>
        </tr>
        <% for(var i = 0; i < bookList.length; i++) { %>
        <tr>
            <td><%= bookList[i].id %></td>
            <td><%= bookList[i].name %></td>
            <td><%= bookList[i].price %></td>
            <td>
                <a href="/detail?id=<%= bookList[i].id %>">查看</a>
                <a href="/delete?id=<%= bookList[i].id %>">删除</a>
            </td>
        </tr>
        <% } %>
    </table>

</body>
</html>

7、node app.js启动项目,浏览器访问主页 :http://127.0.0.1:8080/

  

  

  

  测试完后data.json文件的数据:

[{"id":1,"name":"射雕英雄传","price":"45.00"},{"id":2,"name":"天龙八部2","price":"66.00"},{"id":3,"name":"倚天屠龙记","price":"50.00"},{"id":4,"name":"Java编程思想2","price":"40.00"},{"name":"Java从入门到精通","price":"30.00","id":6},{"name":"ggf","price":"fff","id":8},{"name":"af","price":"ff","id":9}]

 

原文地址:https://www.cnblogs.com/xy-ouyang/p/11141206.html

时间: 2024-10-29 19:05:51

node.js入门学习(四)--Demo的相关文章

node.js入门学习(四)--Demo模块化改造

1.node.js中模块的分类 1)node.js内置模块(核心,原生) 所有内置模块在安装node.js时就已经编译成二进制文件,可以直接加载运行(速度较快),部分内置模块,在node.exe这个进程启动时就已经默认加载了,可以直接使用. 2)文件模块 require(./common.js); // 去当前js文件的路径下找commom.js文件并导入执行.如果导入时没有指定文件后缀require(./commom),那么就按照commom.js,common.json,commom.nod

Node.js入门学习笔记(三)

基于事件驱动的回调 这个问题不好回答,不过这是Node.js原生的工作方式.它是事件驱动的,这也是它为什么这么快的原因.你可以花一点时间阅读一下Felix Geisendörfer的大作 Understanding node.js 可了解一些背景知识. 当我们使用http.createServer方法的时候,我们当然不只是想要一个侦听某个端口的服务器,我们还想要这在服务器收到一个HTTP请求的时候做点什么. 问题是,这是异步的,请求任何时候都可能到达,但是我们的服务器却跑在一个单进程中. 写PH

node.js入门学习

一.node.js介绍 1.1.node.js是什么 官网首页总结:Node.js® 是一个基于 Chrome V8 引擎 的 JavaScript 运行时. 1)node.js是一个开发平台,就像java开发平台..net开发平台.PHP开发平台.Apple开发平台一样. - 什么是开发平台:有对应的编程语言.有语言运行时.有能实现特定功能的API(SDK Software Development Kit) 2)node.js平台使用的编程语言是JavaScript. 3)node.js平台是

node.js入门学习(四)--express

1.官网:http://expressjs.com/ 中文:http://www.expressjs.com.cn/ 2.HelloWorld 1)mkdir node-express-demo 2)cd .\node-express-demo\ 3)新建app.js文件 4)npm init -y  : 会以app.js为入口文件,创建package.json 5)npm install express --save  : 本地安装express并将其保存到依赖列表中,会新建package-l

node.js入门学习(二)

一.构建http服务程序-根据不同请求做出不同响应 // 加载http模块 var http = require("http"); // 创建一个http服务对象 http.createServer(function(req, res) { if(req.url === '/') { res.end("hello index"); } else if(req.url === '/list') { res.end("hello list"); }

Node.js入门学习笔记(二)

函数传递 举例来说,你可以这样做: function say(word) {     console.log(word); } function execute(someFunction, value) {    someFunction(value); } execute(say, "Hello"); 请仔细阅读这段代码!在这里,我们把say函数作为execute函数的第一个变量进行了传递.这里返回的不是say的返回值,而是say本身! 这样一来,say就变成了execute中的本地

Node.js入门笔记

第一步自然是安装了,我是用Webstorm这个ide,安装分2步: 1.安装nodejs,下载Windows下的安装版本,注意是以msi为扩展名的,然后下一步,没啥好说的,下载地址如下: 32位的msi:http://nodejs.org/dist/latest/ 64位的msi:http://nodejs.org/dist/latest/ 2.安装WebStorm8.0.3,好像会自动找到nodejs的安装路径,不需要配置啥东东: 装好WebStorm,启动它,然后创建项目(New Proje

Node.js的学习资源、教程和工具

这篇文章编译整理自Stack Overflow的一个如何开始学习Node.js的Wiki帖,这份资源列表在SO上面浏览接近60万次,数千个收藏和顶.特意整理发布到这里,其中添加了部分中文参考资料. 学习指南和教程 NodeSchool.io 交互式课程 Node的艺术 (Node简介) Hello World Hello World Web Server Node.js 指南 使用Node.js, express和MongoDB创建一个博客 Node+MongoDB 100分钟建站攻略 Proj

Windows 下 Node.js 入门

例子工程在此下载 Windows 下 Node.js 入门 NodeJS的历史就不说了,别人说过了.最最关键Google JavaScript V8 开发成功,运行效率很高,开放二次开发接口(C++库,功能类似常见的Lua,Python等脚本的的开放库).本来V8主要给Chrome浏览器服务的,经不住运行效率太优秀了,所以就有人动起了开发Native端的JavaScript运行环境的主意.NodeJS是这个思路的产物. 这是官网 https://nodejs.org/ 英文 https://no