nodejs的基本学习(四)——express与mongodb

nodejs的基本学习(四)——express与mongodb

前言:

承接前面的内容

 

 

 

 

 


express:

Express 是一个简洁而灵活的 node.js Web应用框架, 提供一系列强大特性帮助你创建各种Web应用。Express 不对 node.js 已有的特性进行二次抽象,我们只是在它之上扩展了Web应用所需的功能。丰富的HTTP工具以及来自Connect框架的中间件随取随用,创建强健、友好的API变得快速又简单。
Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用,和丰富的 HTTP 工具。

 

随着Ajax( 即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指一种创建交互式、快速动态网页应用的网页开发技术,无需重新加载整个网页的情况下,能够更新部分网页的技术。)的出现,实现了前后端分离,前端,后端只要通过API接口就可以实现数据的操作

例如 http://baidu.com/user/login?us=123&ps=456 这就是一个api接口,这个结构中用get方法传递了两个数据。

接下来,我们来使用express实现一个基本登录接口逻辑。

 

在学习过程中我们会用到的API文档,express是一个框架,其实也可以理解成一个第三方的插件

 

express安装:

很简单,在npm init后,直接

npm install express

即可

 

express接口与GET/POST传参

首先我们先通过express开启一个服务器

const express= require("express")
//把express做一个实例化
const app=express()

//通过express,开启了一个node的服务器(监听在3000端口)
app.listen(3000,()=>{
    console.log('server start')
}) 

只要五行代码,非常简单

然后我们利用send即可做出一个api接口

const express= require("express")
//把express做一个实例化
const app=express()

//一个最简单的api接口
//示例请求用的get方法
app.get('/user/login',(request,response)=>{
    console.log('你好')
    response.send('注册成功')
}) 

//通过express,开启了一个node的服务器(监听在3000端口)
app.listen(3000,()=>{
    console.log('server start')
}) 

这其实就是我们又做了一个服务器

服务器知识扩充:

  • 服务器本质:一台电脑
  • 服务器软件:比如我们上面的node就是一个服务器软件(再比如php的Apache、java的tomcat、Microsoft的IIS,Linux常用的ngnix)
  • 另外:phpstudy是一个PHP调试环境的程序集成包,内部该程序包集成最新Apache+PHP+MySQL+phpMyAdmin+ZendOptimizer,一次性安装,无须配置即可使用,是非常方便、好用的PHP调试环境。

那我们再来接收一下get传参,和基本学习(二)的套路一样,获取请求的query即可

const express= require("express")
//把express做一个实例化
const app=express()

//一个最简单的api接口
//示例请求用的get方法
app.get('/user/login',(request,response)=>{
    console.log(request.query)
    console.log('你好')

    //解构赋值
    let {us,ps}=request.query
    if(us=='xiaoming'&&ps==456){
        response.send({err:0,msg:'login OK'})
    }else{
        response.send({err:-1,msg:'us pass no ok'})
    }
}) 

//通过express,开启了一个node的服务器(监听在3000端口)
app.listen(3000,()=>{
    console.log('server start')
}) 

可知,get请求用户的传递数据是由后端决定的

接下来我们来看POST请求,这里我们不再做前端页面发送POST了,我们来利用一个插件——POSTMAN

我用的是Chrome浏览器,直接在商店搜索下载即可

基本操作页面就是如上,左边可以更换请求方式,测试接口非常方便

测试一下我们刚刚写的get接口

很好,接下来我们来尝试发送POST请求,加入这样的函数

//一个注册的接口,用的POST
app.post('/user/reg',(req,res)=>{
    //接收POST 数据
    //POST数据一般放在消息体 、请求体中
    console.log(req.body)
    res.send({err:0,msg:'regist  OK'})
}) 

然后在POSTMAN中发送POST数据,注意此时不再是发送param字段,我们选择body去发送消息体,选择表单形式,如下:

send之后,我们会发现VSCode的终端中出现:

undefined

这是我们要他打印消息体所出现的错误,这说明接口测试成功,POST确实会触发这个函数。

至于为什么会打印出 undefined ,这是因为express不能直接解析消息体,需要借助第三方插件实现解析(body-parser)

body-parser网站

还是老样子,使用 npm install body-parser 即可安装

通常POST传参有这么几种数据格式

  • 表单:application/x-www-form-urlencoded
  • json:application/json
  • 图片:form-data

正如官网所示,我们先导入body-parser模块

const bodyparser=require("body-parser")

然后使用app.use来指定express使用第三方插件

app.use(bodyparser.urlencoded({extends:false}))

最后整体代码如下:

const express= require("express")
const bodyparser=require("body-parser")

//把express做一个实例化
const app=express()

//app.use表示使用一个插件
//urlencoded({extends:false})是用来解析表单的数据
app.use(bodyparser.urlencoded({extends:false}))

//一个最简单的api接口
//示例请求用的get方法
app.get('/user/login',(request,response)=>{
    console.log(request.query)
    console.log('你好')

    //解构赋值
    let {us,ps}=request.query
    if(us=='xiaoming'&&ps==456){
        response.send({err:0,msg:'login OK'})
    }else{
        response.send({err:-1,msg:'us pass no ok'})
    }
})  

//一个注册的接口,用的POST
app.post('/user/reg',(req,res)=>{
    //接收POST 数据
    //POST数据一般放在消息体 、请求体中
    console.log(req.body)
    res.send({err:0,msg:'regist  OK'})
}) 

//通过express,开启了一个node的服务器(监听在3000端口)
app.listen(3000,()=>{
    console.log('server start')
}) 

然后用postman做测试,输出端就可以看见正确的结果(即app.body被正确解析)

使用json也是一样的道理

加一句 app.use(bodyparser.json()) 即可

 

路由:

为了更方便管理文件,我们可以使用路由。

入口文件写成这样

const express= require("express")
const bodyparser=require("body-parser")

//把express做一个实例化
const app=express()


let userRouter=require('./router/userRouter')

app.use('/user',userRouter)

//通过express,开启了一个node的服务器(监听在3000端口)
app.listen(3000,()=>{
    console.log('server start')
})  

而./router/userRoute文件写成这样:

const express= require("express")
//获取路由的实例
const router=express.Router()

router.get('/add',(req,res)=>{
    res.send('user add')
})

router.get('/del',(req,res)=>{
    res.send('user del')
})

//对外打包
module.exports=router

这样,当客户访问/user/del,就会分层处理,定位到./router/userRoute文件的第二个get函数。

 

中间件(middleware):

令牌token:

我们先来了解一个东西——令牌 token:

Token 是在服务端产生的。如果前端使用用户名/密码向服务端请求认证,服务端认证成功,那么在服务端会返回 Token 给前端。前端可以在每次请求的时候带上 Token 证明自己的合法地位。

即我们需要设置一个前后端约定的字符串,以防止不怀好意的第三方使用后端的接口

我们来做个简单的实验,代码如下:

const express= require("express")

//把express做一个实例化
const app=express()

app.get('/test1',(req,res)=>{
    let {token}=req.query
    if(token){
        res.send('ok')
    }else{
        res.send('no ok')
    }
})

app.get('/test2',(req,res)=>{
    let {token}=req.query
    if(token){
        res.send('ok')
    }else{
        res.send('no ok')
    }
})

//通过express,开启了一个node的服务器(监听在3000端口)
app.listen(3000,()=>{
    console.log('server start')
})  

令牌token是个好东西,可是难到我们要每个接口都写一个token吗?这太不效率了,我们可以集中管理,这就是中间件的作用。

中间件:

中间件结构:app.use([path],function)

path:是路由的url,默认参数‘/’,意义是路由到这个路径时使用这个中间件

function:中间件函数

这个中间件函数可以理解为就是function(request,response,next)

中间键可以理解为在符合路径的情况下,进入相应的api处理函数之前要过得一个函数,例如上面示例中,不管是/test1还是/test2都要经过/,所以我们的中间键可以这样写:

//使用中间件(第一个参数默认值就是'/',可以不写,直接用回调函数)
app.use('/',(req,res,next)=>{
    console.log("中间件")
    let {token}=req.query
    if(token){
        //是否继续往下执行
        next();
    }else{
        res.send('缺少token')
    }
})

通过中间件就实现了全局的拦截,一定要使用next,它才会往后走。

这样在到达每个接口处理函数之前就都会经过中间件验证token

中间件有三个种类:

  • 自定义中间件
  • 内置中间件
  • 第三方中间件

上面我们的示例就属于自定义中间件,而且是全局的中间件(所有接口都走这个)。

很多机灵的朋友也反应过来了,我们前面用的解析res.body的第三方插件,例如解析json格式

app.use(bodyparser.json()) 

也是在use中加入了一个回调函数,对,这就是第三方中间件

另外再提一下,有全局中间件就有局部中间件,局部中间件就是对app.get直接加个参数

app.get('/test1',(req,res,next)=>{
    console.log('fun1')
    next()
},(req,res)=>{
    console.log('fun2')
    res.send('test1')
})

这样,在进入第二个回调函数之前必须经过第一个回调函数并且在第一个回调函数中得有next允许它继续往下走。(局部中间件不止可以有一个,可以继续弄多层,每一个next都是到下一层)

最后我们再聊一下内置中间件

express.static 是Express目前唯一内置的一个中间件。用来处理静态资源文件。

static还有一个高大上的名字叫做静态资源目录。

什么是静态资源目录,就是说这个目录下的东西,可以被访问。

正如某服务器软件的WWW目录

废话不多说,看代码

const express= require("express")
//node的内置模块,专门用来处理物理路径
const path=require('path')

//把express做一个实例化
const app=express()


app.use(express.static(path.join(__dirname,'./wusuowei')))

//通过域名:端口可以直接指向我们的静态目录
app.listen(3000,()=>{
    console.log('server start')
})   

代码所在文件的同目录下有一个叫 wusuowei 的目录,我们想把它设置成静态资源目录,使用app.use即可。注意,参数必须是绝对路径(绝对路径的获取请借助 path 模块,__dirname可以得到当前文件所在目录,path.join可以拼接两个路径字符串)。

其实前面还有一个参数,就是根目录“/”,只不过可以默认不写

app.use('/',express.static(path.join(__dirname,'./wusuowei')))

如果不是 ‘/’,而是比如 ‘public’,那么访问 域名:端口/public 才会进入 静态资源目录中


Mongodb:

安装:

我们来学习一下著名的非关系型数据库MongoDB

官网献上

下载好安装包后,双击进行安装

下面说几个安装中需要注意的点:

  • custom:自定义安装,选好路径
  • 不必将MongoDB作为service写入

  • Compass(罗盘)不要点

然后没啥了,install即可。

打开命令行工具,进入安装路径的bin目录下,使用命令 mongod,会发现如下:

为什么会报错?我们可以看见倒数第五行的信息

 exception in initAndListen: NonExistentPath: Data 
directory D:\data\db\ not found., terminating

没有找到目录 D:\data\db,好,我们手动给他建造一个data目录,再在里面新建一个db目录。

再次输入mongod(命令行启动mongodb),mongodb就启动成功了,这个cmd框不要关闭。

同bin目录下输入mongo(命令行操作数据库指令)

出现这样的命令行界面,即开启了mongodb中

 

  • 我们是4.0+的mongodb,所以不需要像网上很多文章那样又要配置目录又要干嘛,很简单就可以开启了!
  • 上面配一下环境变量就可以不用专门进某目录去调用mongodb了。

非关系型数据库:

什么是非关系型数据库?他与关系型数据库有什么区别?

以下内容为转载

关系型数据库

关系型数据库最典型的数据结构是表,由二维表及其之间的联系所组成的一个数据组织
优点:
1、易于维护:都是使用表结构,格式一致;
2、使用方便:SQL语言通用,可用于复杂查询;
3、复杂操作:支持SQL,可用于一个表以及多个表之间非常复杂的查询。
缺点:
1、读写性能比较差,尤其是海量数据的高效率读写;
2、固定的表结构,灵活度稍欠;
3、高并发读写需求,传统关系型数据库来说,硬盘I/O是一个很大的瓶颈。

非关系型数据库

非关系型数据库严格上不是一种数据库,应该是一种数据结构化存储方法的集合,可以是文档或者键值对等。
优点:
1、格式灵活:存储数据的格式可以是key,value形式、文档形式、图片形式等等,文档形式、图片形式等等,使用灵活,应用场景广泛,而关系型数据库则只支持基础类型。
2、速度快:nosql可以使用硬盘或者随机存储器作为载体,而关系型数据库只能使用硬盘;
3、高扩展性;
4、成本低:nosql数据库部署简单,基本都是开源软件。

缺点:
1、不提供sql支持,学习和使用成本较高;
2、无事务处理;
3、数据结构相对复杂,复杂查询方面稍欠。

 

 


 

商业转载 请联系作者获得授权,非商业转载 请标明出处,谢谢

 

发表评论

是的,我就是计算机界的枭雄!