nodejs入门(三)

文章目录

MongoDb数据库介绍、安装、使用

介绍

MongoDb安装

略,参考其他网站

使用

配置path到MongoDb的安装文件夹下的bin中,打开cmd 输入:mongo命令看看是否成功。如果出来下图说明mongodb 配置成功。

在mongodb4.x 之前我们必须手动启动mongodb,但是mongodb4.x以后不需要手动启动mongodb 了,它默认会开机启动

MongoDB数据库创建删除、表(集合)创建删除、数据增删改查

连接数据库

查看所有数据库列表

show dbs

创建数据库、查看、删除数据库

使用数据库、创建数据库

use test

如果真的想把这个数据库创建成功,那么必须插入一个数据。
数据库中不能直接插入数据,只能往集合(collections)中插入数据。下面命令表示给itying数据库的user表中插入数据

db.user.insert({"name":"xiaoming"});

查看数据库

show dbs

显示当前的数据集合(mysql 中叫表)

show collections

删除集合,删除指定的集合删除表

db.COLLECTION_NAME.drop() # 删除集合

db.user.drop()

删除数据库,删除当前所在的数据库

db.dropDatabase();

插入(增加)数据

插入数据,随着数据的插入,数据库创建成功了,集合也创建成功了

db.test.insert({"name":"xiaoming", "age":41});

查找数据

先插入几条测试记录

db.user.insert({"name":"xiaoming1", "age":11});
db.user.insert({"name":"xiaoming1", "age":15});
db.user.insert({"name":"xiaoming2", "age":18});
db.user.insert({"name":"xiaoming3", "age":22});
db.user.insert({"name":"xiaoming4", "age":41});
db.user.insert({"name":"mongoxiaoming4", "age":46});
db.user.insert({"name":"111mongoxiaoming4", "age":56});

查询所有记录

db.user.find();

相当于:select* from user;

查询去掉后的当前聚集集合中的某列的重复数据

db.user.distinct("name");

会过滤掉name 中的相同数据
相当于:select distict name from user;

查询的记录

查询age = 22 的记录

db.user.find({"age": 22});

相当于: select * from user where age = 22;

查询age > 22 的记录

db.user.find({age: {$gt: 22}});

相当于:select * from user where age >22;

查询age < 22 的记录

db.user.find({age: {$lt: 22}});

相当于:select * from user where age <22;

查询age >= 25 的记录

db.user.find({age: {$gte: 25}});

相当于:select * from user where age >= 25;

查询age <= 25 的记录

db.user.find({age: {$lte: 25}});

查询age >= 23 并且age <= 26

db.user.find({age: {$gte: 23, $lte: 26}});

查询name中包含mongo 的数据模糊

db.user.find({name: /mongo/});

select * from user where name like ‘%mongo%’;

查询name中以mongo开头的

db.user.find({name: /^mongo/});

select * from user where name like ‘mongo%’;

查询指定列name、age 数据

db.user.find({}, {name: 1, age: 1});

相当于:select name, age from user;
当然name也可以用true或false,当用ture的情况下河name:1效果一样,如果用false就是排除name,显示name以外的列信息

查询指定列name、age 数据, age > 25

db.user.find({age: {$gt: 25}}, {name: 1, age: 1});

相当于:select name, age from user where age >25;

按照年龄排序1升序-1降序
升序:

db.user.find().sort({age: 1});

降序:

db.user.find().sort({age: -1});

查询name = zhangsan, age = 22 的数据

db.user.find({name: 'zhangsan', age: 22});

相当于:select * from user where name = ‘zhangsan’ and age = ‘22’;

查询前5条数据

db.user.find().limit(5);

相当于:selecttop 5 * from user;

查询10条以后的数据

db.user.find().skip(10);

查询在5-10之间的数据

db.user.find().limit(10).skip(5);

可用于分页,limit 是pageSize,skip 是(page-1)*pageSize

or与查询

db.user.find({$or: [{age: 22}, {age: 25}]});

findOne查询第一条数据

db.user.findOne();

相当于:selecttop 1 * from user;
db.user.find().limit(1);

查询某个结果集的记录条数统计数量

db.user.find({age: {$gte: 25}}).count();

相当于:select count(*) from user where age >= 20;
如果要返回限制之后的记录数量,要使用count(true)或者count(非0)
db.users.find().skip(10).limit(5).count(true);

修改数据

修改里面还有查询条件。你要该谁,要告诉mongo。
查找名字叫做小明的,把年龄更改为16岁:

db.user.update({"name":"xiaoming2"},{$set:{"age":16}});

更改所有匹配项目:

db.user.update({"name":"xiaoming1"},{$set:{"age":33}},{multi: true});

完整替换,不出现$set关键字了:

db.user.update({"name":"xiaoming3"},{"name":"大明","age":16});
db.user.update({"name": "xiaoming2"}, {$inc: {"age": -2}}, false, true )

相当于:update users set age = age + 50 where name = ‘Lisi’;

db.user.update({"name": 'xiaoming3'}, {$inc: {age: 50}, $set: {name: 'xiaoming33'}}, false, true);

相当于:update users set age = age + 50, name = ‘xiaoming33’ where name = ‘xiaoming3’;

删除数据

db.user.remove({"name":"xiaoming2"}) // collectionsNames为user
db.user.remove({age: 33});

或者

db.user.remove({ "age": 16 }, { justOne: true })

MongoDb 大数据查询优化、MongoDB索引、复合索引、唯一索引、explain分析查询速度

索引基础

索引是对数据库表中一列或多列的值进行排序的一种结构,可以让我们查询数据库变得更快。MongoDB的索引几乎与传统的关系型数据库一模一样,这其中也包括一些基本的查询优化技巧

先插入几条测试记录

db.user.insert({"username":"xiaoming1", "age":11});
db.user.insert({"username":"xiaoming1", "age":15});
db.user.insert({"username":"xiaoming2", "age":18});
db.user.insert({"username":"xiaoming3", "age":22});
db.user.insert({"username":"xiaoming4", "age":41});
db.user.insert({"username":"mongoxiaoming4", "age":46});
db.user.insert({"username":"111mongoxiaoming4", "age":56});

查询是否插入成功

db.user.find()

下面是创建索引的命令:

db.user.ensureIndex({"username":1})

执行后显示:

获取当前集合的索引:

db.user.getIndexes()

删除索引的命令是:

db.user.dropIndex({"username":1})

如果想知道find的时间,则可以使用explain,比如

db.user.find().explain("executionStats")

在MongoDB中,我们同样可以创建复合索引,如:
数字1 表示username键的索引按升序存储,-1表示age键的索引按照降序方式存储

db.user.ensureIndex({"username":1, "age":-1})

该索引被创建后,基于username和age的关联查询将会用到该索引,或者是基于username的查询也会用到该索引,但是只是基于age的查询将不会用到该复合索引。因此可以说,如果想用到复合索引,必须在查询条件中包含复合索引中的前N个索引列。然而如果查询条件中的键值顺序和复合索引中的创建顺序不一致的话,MongoDB可以智能的帮助我们调整该顺序,以便使复合索引可以为查询所用。如:

db.user.find({"age": 11, "username": "xiaoming1"})

对于上面示例中的查询条件,MongoDB在检索之前将会动态的调整查询条件文档的顺序,以使该查询可以用到刚刚创建的复合索引

对于上面创建的索引,MongoDB都会根据索引的keyname和索引方向为新创建的索引自动分配一个索引名,下面的命令可以在创建索引时为其指定索引名,如:

db.user.ensureIndex({"username":1},{"name":"userindex"})

也就是这里的name是可以指定的

随着集合的增长,需要针对查询中大量的排序做索引。如果没有对索引的键调用sort,MongoDB 需要将所有数据提取到内存并排序。因此在做无索引排序时,如果数据量过大以致无法在内存中进行排序,此时MongoDB将会报错。

唯一索引

新建测试数据

db.user.drop()
db.user.insert({"username":"xiaoming1", "age":15});
db.user.insert({"username":"xiaoming2", "age":18});
db.user.insert({"username":"xiaoming3", "age":22});
db.user.find()

在缺省情况下创建的索引均不是唯一索引。下面的示例将创建唯一索引,如:

db.user.ensureIndex({"username":1},{"unique":true})

如果再次插入username重复的文档时,MongoDB将报错,以提示插入重复键,如:

db.user.insert({"username":"xiaoming1", "age":15});

提示

test.user index: username_1 dup key: { : \"xiaoming1\" }"

如果插入的文档中不包含username键,那么该文档中该键的值为null,如果多次插入类似的文档,MongoDB将会报出同样的错误,如:

db.user.insert({"userid1":5})
db.user.insert({"userid1":51})

提示

"errmsg" : "E11000 duplicate key error collection: test.user index: username_1 dup key: { : null }"

如果在创建唯一索引时已经存在了重复项,我们可以通过下面的命令帮助我们在创建唯一索引时消除重复文档,仅保留发现的第一个文档,如:
先删除刚刚创建的唯一索引。

db.user.dropIndex({"username":1})

插入测试数据,以保证集合中有重复键存在。

db.user.remove()
db.user.insert({"userid":5})
db.user.insert({"userid":5})

重新创建唯一索引

db.user.ensureIndex({"userid":1},{"unique":true })

我们同样可以创建复合唯一索引,即保证复合键值唯一即可。如:

db.user.ensureIndex({"userid":1,"age":1},{"unique":true})

索引的一些参数

如果在为已有数据的文档创建索引时,可以执行下面的命令,以使MongoDB在后台创建索引,这样的创建时就不会阻塞其他操作。但是相比而言,以阻塞方式创索引,会使整个创建过程效率更高,但是在创建时MongoDB将无法接收其他的操作

db.user.ensureIndex({"username":1},{"background":true})

使用explain

explain 是非常有用的工具,会帮助你获得查询方面诸多有用的信息。只要对游标调用该方法,就可以得到查询细节。explain会返回一个文档,而不是游标本身。如:

explain 会返回查询使用的索引情况,耗时和扫描文档数的统计信息。

explain executionStats 查询具体的执行时间

db.tablename.find().explain("executionStats")
关注输出的如下数值:explain.executionStats.executionTimeMillis

db.user.find().explain("executionStats")

Mongodb4.x的使用以及Mongodb账户权限配置

参考:Mongodb4.x的使用以及账户权限配置MongoDB 4.X用户和角色权限管理总结

MongoDB 的高级查询 aggregate聚合管道

参考:MongoDB的高级查询aggregate聚合管道MongoDB高级查询_aggregate聚合管道MongoDB高级查询aggregate聚合管道

Nodejs操作MongoDb数据库

在Nodejs中使用Mongodb

需要引包

npm install mongodb --save-dev
npm install ejs --save-dev

参考:MONGODB NODE.JS DRIVER

Nodejs连接MongoDb数据库

需要先在本地安装npm的依赖,安装完成后,用bin下的mongo.exe查看当前的链接

下面的代码均参考官网

新建测试数据

db.user.drop()
db.user.insert({"name":"xiaoming1", "age":15});
db.user.insert({"name":"xiaoming2", "age":18});
db.user.insert({"name":"xiaoming3", "age":22});
db.user.insert({"name":"xiaoming4", "age":22});
db.user.insert({"name":"xiaoming5", "age":22});
db.user.find()

在views文件夹下新建一个index.ejs文件,方便显示数据,内容如下

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
  <title></title>
</head>
<body>
    <h2>这是一个ejs的后台模板引擎111</h2>
    <h2><%=msg%></h2>
    <ul>
        <%for(var i=0;i<list.length;i++){%>
            <li><%=list[i].name%></li>
        <%}%>
    </ul>
</body>
</html>

为app.js新建大体的框架,主要是链接设置与模块的加载

var http = require('http');
var url = require('url');
var ejs = require('ejs');

var mongodb_url = 'mongodb://127.0.0.1:27017'; // 连接数据库的地址   test表示数据库的名称
var { MongoClient } = require('mongodb');
var dbName = 'test'; // dbs name

http.createServer(function (req, res) {
    let pathname=url.parse(req.url).pathname;
    ... 填写nodejs对MongoDb的操作...
}).listen(8081);

console.log('Server running at http://127.0.0.1:8081/');

Nodejs查找MongoDb数据

从MongoDb中读取数据,然后渲染到index.ejs文件中

if(pathname=='/') {
    var msg='这是数据库的数据'
    // ejs.renderFile('./views/index.ejs',{msg:msg, list:""},function(err,data){
    //     res.writeHead(200, { 'Content-Type': 'text/html;charset="utf-8"' });
    //     res.end(data);
    // })
    var client = new MongoClient(mongodb_url, { useUnifiedTopology: true });
    client.connect(function(err){  /*连接数据库*/
        if(err){
            console.log(err);
            console.log('数据库连接失败');
            return;
        }
        list = []
        let db = client.db(dbName);
        // 查找数据
        var result=db.collection('user').find({});
        result.each(function(error,doc){
            if(error){
                console.log(error);
            }else{
                if(doc!=null){
                    list.push(doc);
                }else{  /*doc==null表示数据循环完成*/
                    /*获取数据以后*/
                    //console.log(list);
                    ejs.renderFile('views/index.ejs',{msg:msg, list:list},function(err,data){
                        res.writeHead(200, { 'Content-Type': 'text/html;charset="utf-8"' });
                        res.end(data);
                    })
                }
            }
        })
    })
}

访问http://127.0.0.1:8081/,可以看到渲染的结果如下

Nodejs给 MongoDb增加数据

if(pathname=='/add') {
    var client = new MongoClient(mongodb_url, { useUnifiedTopology: true });
    client.connect(function(err){  /*连接数据库*/
        if(err){
            console.log(err);
            console.log('数据库连接失败');
            return;
        }
        let db = client.db(dbName);
        // 增加数据
        db.collection('user').insertOne({
            "name":"zengraoli2",
            "age":10
        },function(error,result){
            res.writeHead(200, { 'Content-Type': 'text/html;charset="utf-8"' });
            if(error){
                res.end('增加数据失败');
                return;
            }
            res.end('增加数据成功');
            client.close();/*关闭数据库*/
        })
    })
}

浏览器访问http://127.0.0.1:8081/add,自动会添加一条name=zengraoli2,age=10的数据

Nodejs修改 MongoDb数据

if(pathname=='/edit') {
    var client = new MongoClient(mongodb_url, { useUnifiedTopology: true });
    client.connect(function(err){  /*连接数据库*/
        if(err){
            console.log(err);
            console.log('数据库连接失败');
            return;
        }
        let db = client.db(dbName);
        // 修改数据
        db.collection('user').updateOne({"name":"xiaoming3"},{$set:{
            "name":"xiaoming333"
        }},function(error,result){
            res.writeHead(200, { 'Content-Type': 'text/html;charset="utf-8"' });
            if(error){
                res.end('修改数据失败');
            } else {
                res.end('修改数据成功');
                client.close();/*关闭数据库*/
            }
        })
    })
}

再次刷新http://127.0.0.1:8081,可以看到已经修改成功数据

Nodejs删除 MongoDb数据

if(pathname=='/delete') {
    var client = new MongoClient(mongodb_url, { useUnifiedTopology: true });
    client.connect(function(err){  /*连接数据库*/
        if(err){
            console.log(err);
            console.log('数据库连接失败');
            return;
        }
        var query=url.parse(req.url, true).query;
        var name=query.name;
        // console.log(name, dbName)
        let db = client.db(dbName);
        // 修改数据
        db.collection('user').deleteOne({"name":name},function(error, resule){
            res.writeHead(200, { 'Content-Type': 'text/html;charset="utf-8"' });
            if(error){
                res.end('删除失败');
                client.close();
                return;
            }
            client.close();/*关闭数据库*/
            res.end('删除数据成功');
        })
    })
}

访问链接http://127.0.0.1:8081/delete?name=xiaoming2,即可删掉name为xiaoming2的数据

express框架介绍、安装、路由、动态路由、get传值

express框架介绍

Express 是一个基于Node.js平台,快速、开放、极简的web开发框架

Express框架是后台的Node框架,所以和jQuery、zepto、yui、bootstrap都不一个东西。Express在后台的受欢迎的程度类似前端的jQuery,就是企业的事实上的标准

Express特点:

  • Express是一个基于Node.js平台的极简、灵活的web应用开发框架,它提供一系列强大的特性,帮助你创建各种 Web 和移动设备应用
  • 丰富的HTTP快捷方法和任意排列组合的Connect中间件,让你创建健壮、友好的 API 变得既快速又简单
  • Express不对Node.js已有的特性进行二次抽象,我们只是在它之上扩展了Web应用所需的基本功能。

express框架安装

安装Express 框架,就是使用npm 的命令

npm init
npm install express --save

静态路由

var express=require('express'); /*引入*/

var app=new express();  /*实例化*/

app.get('/',function(req,res){

    res.send('你好express');
})

app.get('/news',function(req,res){

    res.send('news模块');
})

app.get('/login',function(req,res){

    res.send('登录模块');
})

app.get('/register',function(req,res){

    res.send('注册模块');
})

动态路由

动态路由则是后面的路由会变化,比如http://127.0.0.1:8081/newscontent/1234与http://127.0.0.1:8081/newscontent/12222

var express=require('express'); /*引入*/

var app=new express();  /*实例化*/
// 动态路由---后面的aid是一直变化的
app.get('/newscontent/:aid',function(req,res){
    // req.params 获取动态路由的传值
    console.log(req.params);
    var aid=req.params.aid;
    res.send('newscontent模块--'+aid);
})

app.listen(8081,'127.0.0.1');

路由的正则匹配:(了解)

app.get('/ab*cd', function(req, res) { 
    res.send('ab*cd'); 
});

get传值

get传值原生模块用的是url模块来解析得到后面的一串,在express里面就方便多了

var express=require('express'); /*引入*/

var app = new express();  /*实例化*/
// 获取get传值 http://localhost:3000/product?aid=123
app.get('/product',function(req, res) {
    // http://localhost:3000/product?aid=123&cid=222
    // req.query获取get传值
    console.log(req.query);
    res.send('product:'+req.query.name+'---'+req.query.age);
})
app.listen(8081,'127.0.0.1');

浏览器访问http://127.0.0.1:8081/product?name=zengraoli&age=37,看到如下内容

express ejs使用 静态文件托管

Express中ejs的安装:

npm install ejs --save

Express中ejs的使用

渲染ejs文件

新建views文件夹,并在里面新建一个index.ejs

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
  <title></title>
</head>
<body>
    <h2>这是一个ejs的后台模板引擎111</h2>
</body>
</html>

在app.js中的express用render去调用这个ejs文件

var express=require('express'); /*引入*/

var app = new express();  /*实例化*/
/*配置ejs模板引擎*/
app.set('view engine','ejs');
app.get('/',function(req,res){
    // res.send('ejs的演示');
    res.render('index');  /*ejs渲染模板*/
})

app.listen(8081,'127.0.0.1');

对ejs进行传值

新建一个news.ejs

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
  <title></title>
</head>
<body>
    <h2>这是一个ejs的后台模板引擎111</h2>
</body>
</html>

此时的app.js内容如下

var express=require('express'); /*引入*/

var app = new express();  /*实例化*/
/*配置ejs模板引擎*/
app.set('view engine','ejs');
app.get('/news',function(req,res){
    // res.send('ejs的演示');
    msg = "ejs222的演示"
    res.render('news', {msg: msg});  /*ejs渲染模板*/
})

app.listen(8081,'127.0.0.1');

指定模板位置,默认模板位置在views

app.set('views', __dirname + '/views');

Ejs引入模板,这样能切分更细小的功能,比如头部或者尾部可以重复利用很多次

<%- include header.ejs %>

在views文件夹下新建一个public文件夹,存放一个header.ejs,内容如下

<h2 class="header">这是外部的一个ejs文件,这是头部文件</h2>

在news.ejs中引入这个header

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
  <title></title>
</head>
<body>
  <%- include('public/header')%>
    <h2><%=msg%></h2>
</body>
</html>

Ejs绑定数据

<%=h%>

Ejs绑定html数据

<%-h%>

Ejs模板判断语句

<% if(true){ %> <div>true</div> <%} else{ %> <div>false</div> <%} %>

Ejs模板中循环数据

<%for(var i=0;i<list.length;i++) { %> <li><%=list[i] %></li> <%}%>

Ejs后缀修改为Html

这是一个小技巧,看着.ejs的后缀总觉得不爽,使用如下方法,可以将模板文件的后缀换成我们习惯的.html
1.在app.js的头上定义ejs:,代码如下: 
var ejs = require('ejs');
2.注册html模板引擎代码如下:
app.engine('html',ejs.__express);
3.将模板引擎换成html代码如下:
app.set('view engine', 'html');
4.修改模板文件的后缀为.html。

利用 Express.static 托管静态文件

以前在调用ejs直接readfile的时候,是通过判断数据类型来进行返回的,express一句话就完成了这个功能

如果你的静态资源存放在多个目录下面,你可以多次调用express.static中间件:

app.use(express.static('public'));

现在,public目录下面的文件就可以访问了。

http://localhost:8081/images/kitten.jpg http://localhost:8081/css/style.css
http://localhost:8081/js/app.js
http://localhost:8081/images/bg.png
http://localhost:8081/hello.html

如果你希望所有通过express.static访问的文件都存放在一个“虚拟(virtual)”目录(即目录根本不存在)下面,可以通过为静态资源目录指定一个挂载路径的方式来实现,如下所示

app.use('/static', express.static('public'));

现在,你就可以通过带有“/static”前缀的地址来访问public目录下面的文件了

http://localhost:8081/static/images/kitten.jpg http://localhost:8081/static/css/style.css http://localhost:8081/static/js/app.js http://localhost:8081/static/images/bg.png http://localhost:8081/static/hello.html

实际测试,新建一个public/css,下面有一个style.css,内容如下

.header{
    background: red;
}

在页面news.ejs中引入这个css

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
  <link rel="stylesheet" href="css/style.css"/>
  <title></title>
</head>
<body>
  <%- include('public/header')%>
    <h2><%=msg%></h2>
</body>
</html>

header.ejs还是原来的

<h2 class="header">这是外部的一个ejs文件,这是头部文件</h2>

app.js代码为

var express=require('express'); /*引入*/

var app = new express();  /*实例化*/
// getpublic目录下的文件提供静态web服务
app.use(express.static('public'));
// 配置虚拟目录 作为静态web服务
// app.use('/static', express.static('public'));
/*配置ejs模板引擎*/
app.set('view engine','ejs');
app.get('/news',function(req,res){
    // res.send('ejs的演示');
    msg = "ejs222的演示"
    res.render('news', {msg: msg});  /*ejs渲染模板*/
})

app.listen(8081,'127.0.0.1');

执行后看到效果,说明静态资源已经成功托管

直接访问链接也可以进行测试http://127.0.0.1:8081/css/style.css

中间件

Express 是一个自身功能极简,完全是由路由和中间件构成一个的web开发框架:从本质上来说,一个 Express 应用就是在调用各种中间件

中间件(Middleware) 是一个函数,它可以访问请求对象(request object (req)), 响应对象(response object (res)), 和 web 应用中处理请求-响应循环流程中的中间件,一般被命名为 next 的变量

中间件的功能包括:

  • 执行任何代码
  • 修改请求和响应对象
  • 终结请求-响应循环
  • 调用堆栈中的下一个中间件

如果我的get、post回调函数中,没有next参数,那么就匹配上第一个路由,就不会往下匹配了。如果想往下匹配的话,那么需要写next()

Express 应用可使用如下几种中间件:

  • 应用级中间件
  • 路由级中间件
  • 错误处理中间件
  • 内置中间件
  • 第三方中间件

应用级中间件

现在需要完成一个功能,在app进行路由匹配之前输出一下系统的时间,那么需要使用到中间件

var express=require('express'); /*引入*/

var app = new express();  /*实例化*/
app.set('view engine','ejs');
// getpublic目录下的文件提供静态web服务
app.use(express.static('public'));
app.use(function(req, res, next){
    console.log(new Date()) 
    next(); // next() 路由继续向下匹配
})
app.get('/news',function(req,res){
    // res.send('ejs的演示');
    msg = "ejs222的演示"
    res.render('news', {msg: msg});  /*ejs渲染模板*/
})

app.listen(8081,'127.0.0.1');

应用级中间件一般用在权限判断中

路由中间件

应用级中间件用的是app.use(也可以让其匹配某个路由app.use(‘路由’,function(…))),路由中间件用的是app.get等

下面是一个多匹配的路由中间件

var express=require('express'); /*引入*/

var app = new express();  /*实例化*/
app.set('view engine','ejs');
// public目录下的文件提供静态web服务
app.use(express.static('public'));
app.use(function(req, res, next){
    console.log(new Date()) 
    next(); // next() 路由继续向下匹配
})

app.get('/news',function(req,res, next){
    console.log('新闻路由')
    next()
})

app.get('/news',function(req,res){
    // res.send('ejs的演示');
    msg = "ejs222的演示"
    res.render('news', {msg: msg});  /*ejs渲染模板*/
})

app.listen(8081,'127.0.0.1');

错误处理中间件

匹配不到路由时候可以做一些操作

var express=require('express'); /*引入*/

var app = new express();  /*实例化*/
app.set('view engine','ejs');

app.get('/news',function(req,res){
    // res.send('ejs的演示');
    msg = "ejs222的演示"
    res.render('news', {msg: msg});  /*ejs渲染模板*/
})

// 匹配所有的路由 访问不存在的路由则会自动触发http://127.0.0.1:8081/news1
app.use(function(req,res){
    res.status(404).send('这是404 表示路由没有匹配到')
})

app.listen(8081,'127.0.0.1');

内置中间件

上面的设置静态web服务的中间件就是内置的

// public目录下的文件提供静态web服务
app.use(express.static('public'));

express第三方中间件body-parser获取Get Post请求的参数

之前获取post提交的数据,使用on来监听data和end事件,这里使用express第三方中间件来获取post提交的数据

GET请求的参数在URL中,在原生Node中,需要使用url模块来识别参数字符串。在Express中,不需要使用url模块了。可以直接使用req.query对象。

POST请求在express中不能直接获得,可以使用body-parser模块。使用后,将可以用req.body得到参数。但是如果表单中含有文件上传,那么还是需要使用formidable模块。

安装body-parser中间件

npm install body-parser --save

包使用介绍:https://www.npmjs.com/package/body-parser

设置中间件,有个这两句之后,提交的数据都存在于requests的body中

// parse application/x-www-form-urlencoded
 app.use(bodyParser.urlencoded({ extended: false }))

// parse application/json
 app.use(bodyParser.json())

具体的例子如下

首先需要在views下新建一个login.ejs

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
  <title></title>
</head>
<body>
<h2>登录页面</h2>
<form action="/doLogin" method="post">
    用户名:<input type="text" name="username"/><br/><br/>
    密 码:<input type="password" name="pass"/><br/><br/>
    <input type="submit" value="登录"/>
</form>
</body>
</html>

这是app.js的代码部分为

var express=require('express'); /*引入*/
var bodyParser=require('body-parser')

var app = new express();  /*实例化*/
app.set('view engine','ejs');
// getpublic目录下的文件提供静态web服务
app.use(express.static('public'));
//配置body-parser中间件
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json());

app.get('/login',function(req,res){
    res.render('login');
})
  
app.post('/doLogin',function(req,res){
    console.log(req.body);   /*获取post提交的数据*/
})

app.listen(8081,'127.0.0.1');

全文所涉及的代码下载地址

参考链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值