nodeJS详解2

nodeJs详解,包括模块化,模块倒入,os模块,path模块,fs模块,http模块,querystring模块,url模块,express详解,express与mongodb、中间件讲解,路由讲解

Nodejs应用场景

  • 创建应用服务
  • web开发
  • 接口开发
  • 客户端应用工具 gulp webpack vue脚手架 react脚手架 小程序

NodeJs基于 Commonjs模块化开发的规范,它定义一个JS文件就称之为一个模块

一、模块导入

CommonJS

导出:module.exports.name

导入:require

var exports = module.exports;

// a.js

exports = function a() {};

// b.js

const a = require('./a.js') // a 是一个空对象

ES6

导出:export {}

export default function(){}

export const function(){}

导入:import

二、Node语法

1、os模块

const os=require('os')

os.cpus() cpu参数

os.totalmem() 内存大小

os.freemem() 内存剩余大小

2、path模块

const path = require('path')

path.basename('路径') 文件名称

path.dirname(路径) 文件路径

path.extname('路径') 文件扩展名

path.join('/a','b','c')    路径拼接

3、url模块

const url = require('url')

const href = '//www.baidu.com/a/b/c/d/a.html?

let { pathname, query } = url.parse(href, true, false)

参数1:url地址

参数2:让query转化为对象

参数3:如果url地址中没有协议则为true时可以得到host相关信息,而默认false将得不到host相关信不影响我们获取query中的参数

4、querystring模块

const querystring=require('querystring')

querystring.parse('foo=99&abc=tt') //字符串转对象

querystring.stringify({foo:'cc',abc:'pp'}) //对象转字符串

5、fs模块

const fs = require('fs')

fs.writeFile('文件路径',data,err=>{}) //文件写入

fs.readFile('文件路径','utf8',(err,data)=>{}) //文件读取

fs.existSync(path)    //文件检测true/flase

fs.stat('文件路径',(err,stats)=>{

stats.isDirectory() //是否是目录

stats.isFile() //是否为文件

stats.size //文件大小

})

fs.unlink('文件路径',err=>{}) //删除文件

6、全局变量

global   类似于js的window

__filename 文件名称

__dirname 目录

7、http模块

一、导入

const http=require('http')

二、创建服务

const server = http.createServer()

三、请求

server.on('request',(request,response)=>{

request:请求对象

request.url 地址

reuest.method 方式get、post..

req.headers 请求头

response:响应对象

response.setHeader() 设置响应头

res.statusCod =200 状态

res.end() 发送数据

})

四、启动服务

server.listen(8080,()=>{})

8、nrm管理npm镜像源

安装:npm i nrm -g

查看:nrm ls

切换:nrm use 名称

9、nodemon自动重启node

npm i nodemon -g

nodemon app.js

写个案例串联一下知识点

const http=require('http')
const server=http.createServer()
const path=require('path')
const fs=require('fs')
const url=require('url')
// const queryString=require('queryString')
const webroot=path.join(__dirname,'src')
const nofont=path.join(webroot,'nofont.html')
server.on('request',(req,res)=>{
    let uri=req.url  //请求地址
    let {pathname,query}=url.parse(uri,true)
    pathname=pathname=='/'?'/index.html':pathname
    if('favicon.ico'!=pathname){
        let filepath=path.join(webroot,pathname)
        fs.readFile(filepath,"utf-8",(err,data)=>{
            if(err){
                res.end(fs.readFileSync(nofont))
            }else{
                res.end(data)
            }
        })
    }
})
server.listen(8090,()=>{
    console.log('is ok server')
})

再写一个练习一下post和get用法

const http = require('http')
const path = require('path')
const fs = require('fs')
const url = require('url')
const querystring = require('querystring')
const webroot = path.join(__dirname, 'src')
http.createServer((req, res) => {
    let uri = req.url
    let { pathName, query } = url.parse(uri, true)
    let extname = path.extname(pathName)
    if ('favicon.ico' != pathName && req.method == 'GET') {
        pathName = pathName == '/' ? 'index.html' : pathName
    }
    // 设置文件路径。针对非html文件
    let filepath = path.join(webroot, pathName)
    if ('.html' == extname) {
        filepath = path.join(webroot, 'src', pathName)
        fs.readFileSync(filepath, 'utf-8', (err, data) => {
            if (err) {
                res.statusCode = 404
                res.end('not found')
            } else {
                res.end(data)
            }
        })
    }else{
        switch(pathName){
            case '/login':
                let data=''
                req.on('data',chunk=>data+=chunk)
                req.on('end',()=>{
                    res.end('post')
                })
                break;
            case '/news':
                let data=[]
                req.on('data',chunk=>data.push(chunk))
                req.on('end',()=>{
                    let postData=Buffer.concat(data).toString()
                    res.end(post)
                })
                break;
            default:
                res.end('not')
        }
    }
}).listen(8082,()=>{
    console.log('post or get')
})

三、express模块

1、下载 npm i express -S

2、基本操作

const express = require('express')
// ① 创建服务
const app = express()
/* 
    ② 监听get
        req:请求对象
        res:响应对象
        res.send():向客户端发送相应数据
 */
app.get('请求url', (req, res) => {
    res.send({
        id: '1',
        name: 'll'
    })
})
/* 
    ③ 启动服务
    命令查看启动是否成功:       netstat -ano |findstr 8080
                    mac/linux:netstat -tunp | grep 8080
*/
app.listen(8080,()=>{})

/* 
    1、use 类似于路由守卫
        作用:接收所有请求,
        next:是否向下执行
        接受所有请求,有一个next参数,此参数定义是否向下执行 路由规则
        参数1:  空     前面的所有规则必须符合
                不为空  前面的单一正确即可
        参数2:回调函数
            1、请求
            2、响应
            3、是否向下执行
            app.use('', (req, res, next) => {
                next(); //处理结束,向下执行,直接匹配到定义了的规则
            })
*/
app.use((req,res,next)=>{
    next()
})

/* 
    2、参数的获取
        get值:      req.query
        动态参数值:  req.params
        post值:     req.body
*/
// 路由参数:api/detail/100/zzhh
app.get('api/detail/:id/:name',(req,res)=>{
    let {id,name}=req.params
    res.send(name,id)
})

/* 
    3、静态资源托管
        express提供了一个非常好用的方法,叫做 express.static(),通过此方法,可以非常方便地创建一个静态web资源服务器
        app.use(express.static('public'))
        现在可以访问public目录下所有的文件 
        如public/aa.jpg文件,则可以通过 : http://xxxx/images/aa.jpg

        挂载路径前缀,希望是访问到指定的路径后才触发到静态资源管理
        app.use('public', express.static('public'))
        如public/aa.jpg文件,则可以通过 : http://xxxx/public/images/aa.jpg
*/
// 访问public下的内容
    app.use(express.static('public'))
    app.use('public', express.static('public'))
    // 44处理
    app.use((req,res,next)=>{
        res.statusCode=404
        res.send('页面丢了')
    })

3、路由

route.js中

          const express=require('express')
            const router=express.Router()
            router.get('/kk',(req,res)=>{
                res.send('')
            })
            module.exports=router 

引入路由

      const express=require('express')
            const app=express()
            app.listen(8080)
            app.use(require('./route.js'))    

4、中间件

自定义中间件err.js

// 错误级别中间件
const express=require('express')
const fs=require('fs')
const path=require('path')
const app=express
app.listen(8080)
app.get('/',(req,res)=>{
    let filepath = path.join(__dirname,'html','index.html')
    try {
        let html=fs.readFileSync(filepath)
        res.send(html)
    } catch (error) {
        throw new Error('读取失败')
    }
})
// 用户模块
app.get('/user',(req,res)=>{
    let username=req.query.username
    if(username!='admin'){
        throw new Error('非法用户')
    }else{
        res.send('成功')
    }
})
app.use((err,req,res,next)=>{
    res.status(500).send(err.message)
})

自定义函数中间件

const express=require('express')
const app=express()
app.listen(8088)
const islogin=(req,res,next)=>{
    let username=req.query.username
    if(username=='1amin'){
        next()
    }else{
        next(err)
    }
}
const logined=(req,res,next)=>{
    req.nickname='lll'
    next()
}
const login=[islogin,logined]
app.get('/login',login,(req,res)=>{
    res.send('用户中心'+req.nickname)
})
app.use((err,req,res,next)=>{
    res.status(401).send('非法登录')
})
// 内置中间件 app.use(express.static('public'))

第三方中间件

// 第三方中间件用于读取表单提交数据 npm i -S body-parser
const express=require('express')
const bodyPaser=require('body-parser')
const app=express()
app.listen(8085)
app.use(express.static('html'))
/* 
    用于post数据接收
*/
app.use(bodyPaser.urlencoded({extended:false}))
app.post('/login',(req,res)=>{
    console.log(req.body)
    res.send('')
})

5、cookie

// npm i -S cookie-parser
const express=require('express')
const bodyPaser = require('body-parser')
const cookieParser=require('cookie-parser')
const app=express()
app.listen(8085)
app.use(express.static('../src'))
app.use(bodyPaser.urlencoded({extended:false}))
app.use(cookieParser())
app.get('/a',(req,res)=>{
    // 写入cookie 设置过期时间五分钟
    res.cookie('userbane',['zhangshan','pp'],{maxAge:5*60*1000})
    res.send('ok')
})
app.get('/b',(req,res)=>{
    console.log(req.cookies)
    res.send(req.cookies)
}) 

6、session

// npm i -S cookie-session
const express = require('express')
const cookieSession =require('cookie-session')
const app=express()
app.listen(8086)
app.use(express.static('../src'))
app.use(cookieSession({
    name:'sessionId',
    secret:'sad加密',
    maxAge:10*60*1000
}))
app.get('/',(req,res)=>{
    // 写session
    if(!req.session.view){
        req.session.view=1
    }else{
        req.session['view']++
    }
    res.send('访问了此页'+req.session.view+'次')
})

四、express与mongodb

const express = require('express')
const mongoose=require('mongoose')
const app=express()
app.listen(8285)
/* 
    1、链接数据库
        兼容高版本
        协议,域名,端口号,库名
*/
mongoose.connect('mongodb://localhost:27017/mydemo',{useNewUrlParser:true,useUnifiedTopology:true})
app.get('/',(req,res)=>{
    res.send('数据库')
})
/* 
    2、定义scamer
        数据表结构的定义;每个schema会映射到mongodb中的一个集合
*/
var useSchema=new mongoose.Schema({
    name:{
        type:String,
        minlength:2,
        require:true
    },
    id:String
})
/* 
    3、model数据炒作
        model名称
        schema名称
        操作的数据集合 没有则以1的形式(表明)
*/
const userModel=mongoose.model('user',useSchema,'user')
userModel.find().then(res=>{
    console.log(res,'sss')
})