node笔记

1.文件操作

let fs=require("fs")
fs.readFile(path,coding,callback)
fs.writeFile(path,content,callback)

2.http模块

//1.加载http核心模块
let http=require("http")
//2.使用http.createServer()创建一个web服务器
let server=http.createServer()
//3.注册request请求事件
//当客户端请求过来,就会触发request请求事件,然后执行
server.on('request',function(req,res){
    //发送内容到客户端
    res.end("收到请求")
})
//4.绑定端口号,启动服务器
server.listen(3000,fn)

3.request和response

//response主要用于(向客户端)发送内容
response.write()
response.end()
//导入express模块
response.send()
//使用express-art-template
response.render()
//request
request.url //请求路径
request.socket.remoteAddress //请求地址
request.socket.remotePort //请求端口

4.Other module

//4.1 os模块
os.cpus()//获取CPU信息
os.totalmem()//获取内存信息

//4.2 url模块
//url.parse()添加true,使query变成对象
url.parse(href,true)
//protocol,host,port,hostname,hash,serch,query,pathname,path,href

//4.3 path模块
path.basename() //文件名+拓展名
path.dirname() //获取文件中目录部分
path.extname() //获取拓展名
path.parse() //把路径转换成对象,包含root,dir,base,ext,name
path.join() //拼接路径
path.isAbsolute() //判断是否是绝对路径

//4.4 其他成员
//__dirname,是一个成员,可以用来动态获取当前文件模块所属目录的绝对路径
//__filename,可以用来动态获取当前文件的绝对路径(包含文件名)

5.模块化

//5.1 模块化里面的console.log()会打印
//5.2 moudle.exports导出,require()导入
//5.3 exports默认是一个对象,如果直接使用module.export=....后面会覆盖前面

6.编码问题和解决跨域方法

//编码问题
//1.response.write(<header><meta charset='utf-8'></header>)

//2.response.setHeader('Content-Type','text/plan;charset=utf-8')

//解决跨域问题
responese.setHeader('Access-Control-Allow-Origin',"*")

//如果客户端发现收到服务器的状态码是302就会自动去响应头中找location
res.statusCode = 302;
res.setHeader('location', '/');

7.使用node创建后端

let http = require('http');
let fs = require('fs');

let server = http.createServer();

//https://tool.oschina.net/commons
server.on('request', function (request, response) {
    let url = request.url;
    if (url == '/') {
        fs.readFile('./data/resource/resource01/index.html', function (err, data) {
            if (err) {
                response.setHeader('Content-Type', 'text/plain; charset=utf-8');
                response.end('文件读取失败');
            }
            else {
                response.setHeader('Content-Type', 'text/html; charset=utf-8');
                response.end(data);
            }
        })
    }
    // application/x-img
    else if (url === '/img') {
        fs.readFile('./data/resource/resource01/ab2.jpg', function (err, data) {
            if (err) {
                response.setHeader('Content-Type', 'text/plain; charset=utf-8');
                response.end('文件读取失败');
            }
            else {
                // data 默认是二进制数据,可以通过.toString()转成字符串
                //res.end()支持两种数据类型,一种是二进制,另一种是字符串
                //图片不需要指定编码,我们常说的编码一般指字符编码
                response.setHeader('Content-Type', 'image/jpeg');
                response.end(data);
            }
        })
    }

});

server.listen(3000, function () {
    console.log('服务器启动成功');
})

8.模板引擎art-template

let fs = require('fs');
let template = require('art-template');

fs.readFile('./12.tpl.htm', function (err, data) {
    if (err) {
        return console.log('文件读取失败');
    }
    // data默认是二进制数据,把 data 二进制数据转为 字符串 才可以给模板引擎使用
    var ret = template.render(data.toString(), {
        name: 'Jack',
        age: 18,
        province: '北京市',
        hobbies: [
            '写代码',
            '唱歌',
            '打游戏'
        ],
        title: '个人信息'
    });
    console.log(ret);
})

9.express基本使用

//1.引包
let express=require("express")

//2.创建服务器应用程序
let app=express()

//公开指定目录
app.use('/public/',express.static('./'))

//3.接收请求
//可以直接得到路径,有utf-8编码
app.get("/about",fn)

//4.监听端口
app.listen(port,fn)

10.express art-template

const express = require('express')
const app = express()
const port = 3000


app.engine('html', require('express-art-template'));
//express为Response相应对象提供了一个方法:render
//render()默认是不可以使用的,但是如果配置了模板引擎就可以使用了
//res.render('html模板名',{模板数据})
//第一个参数不能写路径,默认会去项目中的views目录查找该模板文件
//Express有一个约定:开发人员把所有的视图文件都放到views目录
app.get('/', (req,res) => {
    res.render('404.html')
})
app.listen(port, () => console.log(`Example app listening on port port!`))

//注: 如果希望修改默认的views视图渲染存储目录,可以:
// app.set('views',目录路径);

11.express实例

const express = require('express')
const app = express()
const port = 3000

var comments = [
    {
        name: 'jack',
        message: 'It is a nice day today',
        dataTime: '2021.4.20'
    },
    {
        name: 'jon',
        message: 'I know',
        dataTime: '2021.4.20'
    },
];
//放出静态资源
app.use('/public/', express.static('./public/'))
//配置模板引擎
app.engine('html', require('express-art-template'));

app.get('/', (req, res) => {
    res.render('index.html', {
        comments
    })
})
app.get('/post', (req, res) => {
    res.render('post.html')
});
app.get('/pinglun', (req, res) => {
    // 获取时间
    let now = new Date();
    let y = now.getFullYear();
    let m = now.getMonth() + 1;
    let d = now.getDate();

    let obj = {
        name: req.query.name,
        message: req.query.message,
        dataTime: (y + '.' + m + '.' + d).toString()
    }

    //   console.log( req.query );
    comments.unshift(obj);
    res.redirect('/');
});

app.listen(port, () => console.log(`Example app listening on port port!`))

12.express获取POST表单数据

//1.加载模块
const bodyParser=require('body-parser')
//2.通过body-parser获取表单post请求数据
app.use(bodyParser.urlencoded({extended:false}))
app.use(bodyParser.json)

app.post(url,function(){
    app.body
})

13.实例

app.js

/**
 * app.js 入门模块
 * 职责:
 *   创建服务
 *   做一些服务相关配置
 *     模板引擎
 *     body-parser 解析表单 post 请求体
 *     提供静态资源服务
 *   挂载路由
 *   监听端口启动服务
 */

const express = require('express');

const router = require('./23.router');

const bodyParser=require('body-parser')
const app = express()

const port = 3000
//放出静态资源
app.use('/node_modules/', express.static('./node_modules'));
app.use('/public', express.static('./public'));
app.engine('html', require('express-art-template'));


// 配置模板引擎bodyParser
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
// 把路由容器挂载到APP服务中
app.use(router)
app.listen(port, () => console.log(`Example app listening on port port!`))

router.js

/**
 * router.js 路由模块
 * 职责:
 *   处理路由
 *   根据不同的请求方法+请求路径设置具体的请求处理函数
 * 模块职责要单一,不要乱写
 * 我们划分模块的目的就是为了增强项目代码的可维护性
 * 提升开发效率
 */
const fs = require('fs')

const express = require('express');

let asyncAPI = require('./23.asyncAPI')

let dbjson;


// 1.创建一个路由容器
let router = express.Router()

// 2. 把路由都挂载到 router 路由容器中
router.get('/', (req, res) => {
    asyncAPI.select(function (err, data) {
        if (err) {
            return res.status(500).send('server error')
        }
        dbjson = data
        res.render('curdIndex.html', {
            fruits: ['苹果', '香蕉', '橙子'],
            student: dbjson.Students,
        });
    })

})
router.get('/students', (req, res) => {
    asyncAPI.select(function (err, data) {
        if (err) {
            return res.status(500).send('server error')
        }
        dbjson = data
        res.render('curdIndex.html', {
            fruits: ['苹果', '香蕉', '橙子'],
            student: dbjson.Students,
        });
    })

})
router.get('/students/new', (req, res) => {
    // 1.获取表单数据
    // 2.处理
    // 将数据保存到db.json文件中持久化
    // 3.发送响应
    res.render('new.html')
})
router.post('/students/new', (req, res) => {
    asyncAPI.add(req.body, function (err) {
        if (err) {
            return res.status(500).send('server error')
        }
        res.redirect('/students')
    })
})

router.get('/students/edit', (req, res) => {
    // console.log(req.query.id);
    // 根据id获取db.json
    asyncAPI.getById(req.query.id, function (err, data) {
        if (err) {
            return res.status(500).send('server error')
        }
        // console.log(data);
        res.render('edit.html', {
            student: data
        })
    })
})
router.post('/students/edit', (req, res) => {
    // console.log("h");
    console.log(req.body);
    asyncAPI.update(req.body, function (err) {
        if (err) {
            return res.status(500).send('server error')
        }
        res.redirect('/students')
    })
})
router.get('/students/delete', (req, res) => {
    //    console.log(req.query);
    asyncAPI.delete(req.query.id, function (err) {
        if (err) {
            return res.status(500).send('server error')
        }
    })

    res.redirect('/students')
})
// 3.导出路由
module.exports = router


asyncAPI.js

/**
 * student.js
 * 数据操作文件模块
 * 职责:操作文件中的数据,只处理数据,不关心业务
 *
 * 这里才是我们学习 Node 的精华部分:奥义之所在
 * 封装异步 API
 */
let fs = require('fs')
let jsonPath = './db.json'
exports.select = function (callback) {
    fs.readFile(jsonPath, 'utf8', function (err, data) {
        if (err) {
            //+callback  防止传参传不出来
            return callback(err)
        }
        callback(null, JSON.parse(data))
    })
}

exports.add = function (obj, callback) {
    fs.readFile(jsonPath, 'utf8', function (err, data) {
        if (err) {
            return callback(err)
        }
        // 转换成对象
        let Students = JSON.parse(data).Students;
        obj.id = Number.parseInt(Students[Students.length - 1].id) + 1
        // 添加对象
        Students.push(obj)
        //将对象转换成字符串
        var fileData = JSON.stringify({
            Students
        })
        fs.writeFile(jsonPath, fileData, function (err) {
            if (err) {
                return callback(err)
            }
            callback(null)
        })
    })
}
exports.update = function (body, callback) {
    //查询找到数组
    // 根据id修改值
    // 写入db.json

    fs.readFile(jsonPath, 'utf8', function (err, data) {
        if (err) {
            return callback(err)
        }
        // console.log(JSON.parse(data));
        let Students = JSON.parse(data).Students
        //   console.log(typeof body.id,typeof Student[1].id);
        for (let i = 0; i < Students.length; i++) {
            if (body.id == Students[i].id) {
                Students[i] = body
            }
        }

        // 将对象转换成字符串
        let fileData = JSON.stringify({
            Students
        })
        fs.writeFile(jsonPath, fileData, function (err) {
            if (err) {
                return callback(err)
            }
            callback(null)
        })
    })



}
exports.delete = function (id, callback) {
    //根据id查询数据
    //转换成数组,splice()
    // 写入文件
    fs.readFile(jsonPath, 'utf8', function (err, data) {
        if (err) {
            return callback(err)
        }
        let Students = JSON.parse(data).Students
        for (let i = 0; i < Students.length; i++) {
            if (Number.parseInt(Students[i].id) === Number(id)) {
                Students.splice(i, 1)
            }
        }
        //  console.log( Students);
        let fileData = JSON.stringify({
            Students
        })
        fs.writeFile(jsonPath, fileData, function (err) {
            if (err) {
                return callback(err)
            }
            callback(null)
        })


    })
}
//获取id
exports.getById = function (id, callback) {
    fs.readFile(jsonPath, 'utf8', function (err, data) {
        let res = [];
        if (err) {
            return callback(err)
        }
        let arr = JSON.parse(data).Students
        for (let i = 0; i < arr.length; i++) {
            if (Number.parseInt(arr[i].id) === Number(id)) {
                res = arr[i];
            }
        }
        callback(null, res)
    })
}

14.MongoDB基本操作

  1. npm install mongoose -S

  2. mongod启动数据库

  3. mongo连接数据库

    14.1 增

    //1.加载模块
    let mongoose=require("mongoose")
    //2.连接数据库
    // 指定连接的数据库不需要存在,当你插入第一条数据后就会自动被创建出来
    mongoose.connect('mongodb://localhost/tableName')
    
    //3.设计表结构
    // 字段名称就是表结构中的属性名称
    // 约束的目的是为了保证数据的完整性
    let Schema=mongoose.Schema
    let userSchema=new Schema({
        username: {
            type: String,
            required: true  //必须有
        },
        password: {
            type: String,
            required: true
        },
        email: {
            type: String
        }
    })
    
    // 4.将文档架构发布为模型
    // mongoose.model()就是用来讲一个架构发布为model
    // 第一个参数:传入一个大写名词单数字符串来表示你的表名称
    // mongoose 会自动将大写名词的字符串生成小写复数的集合名称
    // 例如,这里的User最终会变成user集合名称,这里的返回值是一个模型构造函数
    let User=mongoose.model('User',userSchema)
    
    //5.保存
    var admin=new User({
        username: "黑漆漆",
        password: "123456",
        email: "admin@qq.com"
    })
    admin.save(function (err, ret) {
        if (err) {
            console.log("error")
        }
        else {
            console.log(ret)
        }
    })
    

    14.2 删

    let mongoose=require('mongoose')
    
    mongoo.connect('mongodb://localhost/tableName')
    
    let Schema=mongoose.Schema
    let userSchema=new Schema({
        username:{
            type:String,
            required:true
        },
        password:{
            type:String,
            required:true
        },
        email:{
            type:String
        }    
    })
    let User=mongoose.model('User',userSchema)
    
    User.remove({
        username:'name'
    },fn(err,res))
    

    14.3 改

    let mongoose=require('mongoose')
    mongoose.connect('mongodb://localhost/tableName')
    
    let Schemm=mongoose.Schema
    let  userSchema=new Schemm({
         username:{
           type:String,
           require:true
         },
         password:{
           type:String,
           require:true
         },
         email:{
            type:String
         }
    })
    let user=mongoose.model('User',userSchema)
    
    user.findByIdAndUpdate('608c05ca79d0220c0c3e0e0b',{
      password:'123'
    },fn(err,res))
    

    14.4 查

    let mongoose = require('mongoose')
    
    // 表结构
    let Schema = mongoose.Schema
    mongoose.connect('mongodb://localhost/itcast')
    var userSchema = new Schema({
        username: {
            type: String,
            required: true  //必须有
        },
        password: {
            type: String,
            required: true
        },
        email: {
            type: String
        }
    })
    
    let User = mongoose.model('User', userSchema)
    
    //查询
    // 第一个参数为对象(查询条件),可选
    // User.find({
    //     username: "陈平安"
    // }, function (err, ret) {
    //     if (err) {
    //         console.log(err)
    //     }
    //     else {
    //         console.log(ret)
    //     }
    // })
    
    // 按条件查询单个
    User.findOne({
        username: "陈平安"
    }, function (err, ret) {
        if (err) {
            console.log(err)
        }
        else {
            console.log(ret)
        }
    })
    
    

15.实例

app.js

/**
 * app.js 入门模块
 * 职责:
 *   创建服务
 *   做一些服务相关配置
 *     模板引擎
 *     body-parser 解析表单 post 请求体
 *     提供静态资源服务
 *   挂载路由
 *   监听端口启动服务
 */

const express = require('express');

const router = require('./31.router');

const bodyParser = require('body-parser')
const app = express()

const port = 3000
//放出静态资源
app.use('/node_modules/', express.static('./node_modules'));
app.use('/public', express.static('./public'));
app.engine('html', require('express-art-template'));


// 配置模板引擎bodyParser
// 通过body-parser获取表单post请求数据
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
// 把路由容器挂载到APP服务中
app.use(router)
app.listen(port, () => console.log(`Example app listening on port port!`))

router.js

/**
 * router.js 路由模块
 * 职责:
 *   处理路由
 *   根据不同的请求方法+请求路径设置具体的请求处理函数
 * 模块职责要单一,不要乱写
 * 我们划分模块的目的就是为了增强项目代码的可维护性
 * 提升开发效率
 */
const fs = require('fs')

const express = require('express');

let asyncAPI = require('./31.mongoo')


// 1.创建一个路由容器
let router = express.Router()

// 2. 把路由都挂载到 router 路由容器中
router.get('/', (req, res) => {
    asyncAPI.find(function (err, data) {
        if (err) {
            return res.status(500).send('server error')
        }
        res.render('McurdIndex.html', {
            fruits: ['苹果', '香蕉', '橙子'],
            student: data,
        });
        // console.log(data[0]._id,typeof data[0]._id)
    })

})
router.get('/students', (req, res) => {
    asyncAPI.find(function (err, data) {
        if (err) {
            return res.status(500).send('server error')
        }
        res.render('McurdIndex.html', {
            fruits: ['苹果', '香蕉', '橙子'],
            student: data,
        });
    })
})
router.get('/students/new', (req, res) => {
    // 1.获取表单数据
    // 2.处理
    // 将数据保存到db.json文件中持久化
    // 3.发送响应
    res.render('Mnew.html')
})
router.post('/students/new', (req, res) => {
    var saveData = new asyncAPI(req.body)
    saveData.save(function (err) {
        if (err) {
            return res.status(500).send("server error")
        }
        res.redirect('/students')
    })
})

router.get('/students/edit', (req, res) => {
    req.query.id = req.query.id.replace(/"/g, "")
    // console.log(req.query.id, typeof req.query.id)
    asyncAPI.findById(req.query.id, function (err, data) {
        if (err) {
            return res.status(500).send('server error')
        }
        res.render('Medit.html', {
            student: data
        })
    })
})
router.post('/students/edit', (req, res) => {

    // console.log(req.body.id, typeof req.body.id)
    let id = req.body.id.replace(/"/g, "")
    asyncAPI.findByIdAndUpdate(id, req.body, function (err) {
        if (err) {
            return res.status(500).send('server error')
        }
        res.redirect('/students')
    })
})
router.get('/students/delete', (req, res) => {
    let id = req.query.id.replace(/"/g, "")
    // console.log(id,typeof id)
    asyncAPI.remove({
        _id: id
    }, function (err) {
        if (err) {
            return res.status(500).send('server error')
        }
    })

    res.redirect('/students')
})
// 3.导出路由
module.exports = router

mongodb.js

let mongoose = require('mongoose')

//1.连接数据库
mongoose.connect('mongodb://localhost/itcast')

// 2.设计表结构
let Schema = mongoose.Schema

let studentSchema = new Schema({
    name: {
        type: String,
        required: true
    },
    gender: {
        type: Number,
        enum: [1, 2],
        default: 1
    },
    age: {
        type: Number
    },
    hobbies: {
        type: String
    }
})

// 直接导出模型构造函数
module.exports = mongoose.model("newBody", studentSchema)

16.实例

app.js

let express = require("express")
let path = require("path")
let router = require('./33.router')
let bodyParser = require("body-parser")
let session = require('express-session')
let app = express()

// 释放静态资源
app.use('/public/', express.static(path.join(__dirname, "./public/")))
app.use('/node_modules/', express.static(path.join(__dirname, "./node_modules")))
app.engine('html', require("express-art-template"))

// 设置资源目录,默认就是 views
app.set('views', path.join(__dirname, './views/'))

// 配置解析表单请求体
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())

// express-session
app.use(session({
    // 配置加密字符串,他会在原有加密基础上和这个字符串拼接起来去加密
    secret: 'keyboard cat',
    resave: false,
    saveUninitialized: true
}))

app.use(router)

app.listen(3000, function () {
    console.log("running")
})

router.js

let express = require('express')
let router = express.Router()
let user = require('./models/user')

let md5 = require('blueimp-md5')


router.get('/', function (req, res) {
    // console.log(req.session.user, typeof req.session.user)
    res.render('NewIndex.html', {
        user: req.session.user
    })
})
router.get('/login', function (req, res) {
    res.render('login.html')
})
router.post('/login', function (req, res) {
    // console.log(req.body)
    req.body.password = md5(md5(req.body.password))
    user.find({
        "email": req.body.email,
        "password": req.body.password
    }, function (err, data) {
        if (err) {
            return res.status(500).json({
                err_code: 500,
                message: "server error"
            })
        }
        if (data.length == 0) {
            return res.status(200).json({
                err_code: 1,
                message: "not found"
            })
        }
        // 登录成功使用session记录登录状态
        req.session.user = data
        // console.log(data.nickname)
        res.status(200).json({
            err_code: 0,
            message: "OK"
        })
        // console.log(data)
    })
})
router.get('/register', function (req, res) {
    res.render('register.html')
})
router.post('/register', function (req, res) {
    // console.log(req.body.email)
    user.find({
        email: req.body.email
    }, function (err, data) {
        if (err) {
            //  express提供了一个响应方法 json
            // 该方法接收一个对象作为参数,会将对象转换成字符串
            return res.status(500).json({
                success: false,
                message: 'server error'
            })
        }
        if (data.length !== 0) {
            // console.log(data)
            return res.status(200).json({
                success: false,
                message: '邮箱已存在'
            })
        }
        // 对密码进行md5重复加密
        req.body.password = md5(md5(req.body.password))
        new user(req.body).save(function (err, data) {
            if (err) {
                return res.status(500).json({
                    success: false,
                    message: 'server error'
                })
            }
            // 注册成功使用session记录用户的登录状态         
            req.session.user = data
            res.status(200).json({
                success: true,
                message: 'OK'
            })
            // 服务端重定向只针对同步请求有效,异步请求无效
            // res.redirect('/')
        })



    })
})
router.get('/topics/new', function (req, res) {
    res.render('topic/new.html')
})
router.get('/logout', function (req, res) {
    req.session.user = ''
    res.redirect('/')
})
module.exports = router

user.js

var mongoose = require('mongoose')

// 连接数据库
mongoose.connect('mongodb://localhost/test')

var Schema = mongoose.Schema

var userSchema = new Schema({
    email: {
        type: String,
        required: true
    },
    nickname: {
        type: String,
        required: true
    },
    password: {
        type: String,
        required: true
    },
    created_time: {
        type: Date,
        // 注意:这里不要写 Date.now() 因为会即刻调用
        // 这里直接给了一个方法:Date.now
        // 当你去 new Model 的时候,如果你没有传递 create_time ,则 mongoose 就会调用 default 指定的Date.now 方法,使用其返回值作为默认值
        default: Date.now
    },
    last_modified_time: {
        type: Date,
        default: Date.now
    },
    avatar: {
        type: String,
        default: '/public/img/avatar-default.png'
    },
    bio: {
        type: String,
        default: ''
    },
    gender: {
        type: Number,
        enum: [-1, 0, 1],
        default: -1
    },
    birthday: {
        type: Date
    },
    status: {
        type: Number,
        // 0 没有权限限制
        // 1 不可以评论
        // 2 不可以登录
        enum: [0, 1, 2],
        default: 0
    }
})

module.exports = mongoose.model('User', userSchema)

posted @ 2021-08-02 22:10  yongerbingxuan  阅读(45)  评论(0)    收藏  举报