笔记

第一篇 Node基础知识:

nodeJs是什么:

  1. 基于Chrom V8 引擎的javascript运行时

2.2009年发布的、现在已经更新到了v12

node.js的安装:node.js.cn网站安装node

node.js怎么去运行:

1.当前文件夹打开控制台,执行node index.js

2.在浏览器中打开 localhost:3000进行监听

npm是什么:

1.node package manager,即nodejs软件包管理者

2.官网https://www.npmjs.com/

3.有几百万的软件包,开源免费

软件包有何用:

1.现代软件工程已经完善且成熟,项目不会从0开始写

2.必须搭配成熟的工具和框架才能满足需求,否则将无人使用

3.每个成熟的开发语言或者环境,都需要成熟的软件包体系

开始使用npm

npm会随着nodejs一起被安装

1.首先要初始化环境:npm init

2.其次,安装插件

npm i lodash --save 安装lodash

lodash插件使用演示:

const _ = require('lodash')

const arr = [1, 2, 3]

const otherArr = _.concat(arr, 4, 5)

console.log(otherArr) // [1, 2, 3, 4, 5]

npm i nodemon --save-dev 安装nodemon

nodemon插件使用演示:

修改配置:


image.png

npm run dev 启动、localhost:3000访问。

--save和 --save-dev的区别:

1.--save安装的插件在package.json文件的dependencies对象中
2.--save-dev安装的插件在package.json文件的devDependencies对象中
devDependencies是开发环境使用,dependencies是生产环境使用。

例如webpack,babel等工具,这些是我们开发阶段使用的,代码提交线上时,不需要这些工具,所以我们将它放入devDependencies即可。但是像axios,vuex这类工具,是我们生产环境所使用的,所以要放入dependencies,即使项目上线后也是需要的。

common.js模块化

es6 moudle
◆export .... 或 export default ...
◆import .. from ...

1、在一个文件里只导出一个内容,直接在最后使用export default xxx;
使用时,在要使用的文件中的script标签里引入,使用import xxx from ‘路径’
2、在一个文件里导出多个内容,比如导出多个函数,直接在定义的函数前面加上export即可;
使用时在要使用的文件中的script标签里,使用import { a,b } from ‘路径’,例如a,b就是导出的内容名 字,比 如图中内容就是import { sum, test } from "./utils";

image.png
image.png
commonjs语法介绍

◆module.exports【输出】
◆require(..)【输入】
◆主要用于nodejs开发

require的三个层级
image.png
commontjs和es6 module的区别:

语法不一样、commontjs是执行时候引入的,是动态的;module是打包时候引入,是静态的(imprt不可以放在if中,要放在最顶层)
commonjs可以在if语句中引入,可以执行时再引入,它是动态的;而ES6 Module必须在最顶层引入,不能在if语句中引入,要提前把所有内容引入才能执行,是静态的。图示:


image.png
image.png

模块化的意义:拆分便于管理,便于多人协作开发,成熟的语言都支持模块化

什么是debug

◆bug 即错误
◆debug即排错,也叫调试
◆编程语言,必须有成熟的debug机制,否则将不可用

inspect调试法

1.修改scrtips,增加--inspect,启动服务
2.打开chrome,访问chrome://inspect
3.增加debugger,重启服务,即可调试
*****具体操作*****:
1、增加--inspect,如"dev": "nodemon --inspect=9229 index.js"

image.png

2、在命令窗口进入文件夹,使用npm run dev启动服务
image.png

3、访问chrome://inspect,然后点击页面中Target中的index.js下的inspect,就可以监听nodejs的服务【在代码中做了修改以后,要把打开的inspect窗口关闭,在chrome://inspect中重新打开inspect窗口才能看到新的打印结果】
4、在代码中添加debugger即可设置断点,程序执行到这里会断一下,然后一步一步往后执行。
打开inspect窗口,再在localhost的界面刷新一下,inspect窗口就会自动弹出并切换到Sources、

第二篇 Node和http:

1、认识res、req

image.png
nodejs启动Web服务【监听http请求】
  1. 使用http模块,启动服务
  2. 本机的IP 127.0.0.1
  3. 本机的域名localhost
    代码演示===》
const http = require('http');
const server =  http.createServer(()=>{})
server.listen(3000)

2、res、req的获取和请求

1.req即Request,res即Response,


image.png
  1. 创建服务时传入参数req和res
const http = require('http');
const server =  http.createServer((req,res)=>{
//使用 res.end() 返回信息给前端【这里返回的信息会显示在页面上】
//使用 req.url 获取当前的url,createServer打印的内容是显示在命令窗口中的。
})
server.listen(3000)
console.log('http请求已经被监听,端口3000')  

3、路由

路由包含什么
  1. 定义methond ,包含get\post
  2. 定义url规则
  3. 定义输入、输出的格式
定义get路由
if(path==='/api/list' && method === 'GET'){
        res.end('this is list router')
    }
定义post路由(无法直接测试,需要使用工具postman)
 if(path ==-'/api/create' && method === 'POST'){
        res.end('this is create router')
    }

测试方式:


image.png

4、querystring

1. 什么是querystring

以 :http://xxx.comlist.htmlkeyword=nba&lang=en&a=100为例:
(1)url问号后面的都是querystring (也叫url参数)
(2)&分割,key=value形式,可继续扩展

2. querystring的作用-->动态网页的基石( web1.0 -- web2.0 )
3. 如何利用querystring实现动态网页

(1)服务端拿到querystring --> 通过url.split('?')[1]获取到querystring
(2)根据不同的querystring,返回不同的内容 -->解析querystring:
再根据‘&’和‘=’把querystring中每个参数的key和value存入一个对象中。
(3)变化querystring,就是变换内容(只要服务端支持) -->根据不同的querystring,返回不同的内容


image.png

代替解析querystring:


image.png

image.png

5、哈希

路由中#后面的内容:


image.png

hash不能让服务端获取,它不能传到服务端去。

结构化与非结构化

◆结构化的数据,易于通过程序访问和分析,如对象和数组
◆非结构化的数据,不易通过程序分析,如字符串
◆编程中的数据,都尽量结构化

6、使用res返回数据

1.返回json数据

res.writeHead(status状态码,{'Content-type': 'application/json'})


image.png

end中返回404


image.png

res.end()中返回的必须是一个字符串,所以使用JSON.stringify()将返回的内容包裹起来。
如果返回的内容是字符串格式,那writeHead中的'Content-type'值就是'text/plain';如果返回的内容是json格式,那writeHead中的'Content-type'值就是'application/json'

2.返回html

Content-type: text/html
代码演示:


image.png

7、获取req body

1、流( stream )的表现

观看视频时,一边加载一边观看
上传文件时,有进度条
网速较慢时,打开网页会先显示一部分,然后继续加载

2、(1)下载

source即服务端,dest即客户端(前端)
下载不仅指大文件,泛指所有的Response Body
(2)浏览器能接收流( stream )数据
服务端res.end(..),会自动以 流 的形式返回
浏览器会识别到 流 ,并持续接收信息(会有进度条)
待全部接收完,再做显示或处理(视频是一段一段的播放)

3、(1)上传

◆source 即客户端(前端),dest即服务端
上传不仅指大文件,泛指所有的Request Body
(2)服务端如何接收流( stream )数据
前端使用Ajax (或Postman )提交数据 Request Body
服务端需要识别 流 ,并接收数据
还要知道何时才能接收完成

代码演示:
if (path === '/api/create' && method === 'POST') {
const reqType = req.headers['content-type'] //获取到请求的数据格式

let bodyStr = ''
req.on('data', chunk => { // 服务端怎么去识别“流",并接收数据
//chunk 即“流”的每一段数据
bodyStr = bodyStr + chunk.toString()
})
req.on('end', () => { //服务端怎么知道流完了
if (reqType === 'application/json') { //json 格式
const body = JSON.stringify(bodyStr)
console.log('body is ', body) //对象格式
}

res.end('接收完成') //异步
})

return
}

测试演示(因为异步,第一次返回404):


image.png

第三篇 Koa2框架

Koa2环境搭建

1、什么是框架frame(类比vue)
◆封装原生代码的 API
◆规范流程和格式
◆让开发人员更加关注于业务代码,提高开发效率

2、 koa2 是 nodejs web server 框架
◆官网和文档 https://koa.bootcss.com/
◆通过 async/await 语法【处理异步】高效编写web server
◆中间件机制,能合理拆分业务代码

koa2安装和使用

初始化npm init
安装npm install koa --save

代码演示:

const Koa = require('koa')
const app = new Koa()

app.use(async(ctx)=>{
    ctx.body = 'hello world'
})
app.listen(3000)

koa2的环境搭建 (koa2创建项目:koa2 test // test是项目文件夹名称)

操作步骤:
1、在全局环境中下载 koa(text4的父级目录),使用脚手架koa-generator创建koa2项目 :
npm install -g koa-generator


image.png

2、进入text4目录,下载依赖包,npm install

3\进入项目中的package.json文件,“scripts”配置项中如果有"dev": "./node_modules/.bin/nodemon bin/www",那么就可以在命令窗口中使用npm run dev启动项目。

4、在浏览器中打开localhost:3000

5、routes文件夹 index.js:


image.png

user.js


image.png

koa2的创建新路由

1、在routes中,添加js文件,代码演示:

const router  = require('koa-router')()
router.prefix('/api')//前缀

// 模拟获取浏览器列表
router.get('/list', async (ctx) => {
    ctx.body = 'api list'
  })
  // 模拟创建留言
  router.post('/create', async (ctx) => {
    ctx.body = 'api create'
  })
  // 输出
  module.exports = router

2、在app.js中引入、注册路由:

const comments= require('./routes/comments')
app.use(comments.routes(), comments.allowedMethods())

koa2处理http请求

1、如何接收和返回数据 ctx 即 res 和 req的集合

2、 ctx可以获取query ,const query = ctx.query; 可以获取Response body,const body = ctx.response body
image.png

中间件与洋葱圈模型

1、为什么使用中间件
拆分业务模块,使代码清晰
统一使用中间件,使得各业务代码都规范标准
扩展性好,易添加、易删除.

2、koa2业务代码都是中间件

3、中间件的规则:
不管是什么类型的中间件(路由的或者自定义的),它都是一个async函数。async函数的第一个参数是ctx,第二个参数是next

4、koa2洋葱圈模型
中间件机制,是koa2的精髓
每个中间件都是async函数
中间件的运行机制,就像洋葱圈
图示:


image.png

image.png

代码演示洋葱圈:

// 演示 koa2 中间件的洋葱圈模型

const Koa = require('koa')
const app = new Koa()

// logger
app.use(async (ctx, next) => {
    await next() // 执行下一个中间件
    const rt = ctx.response.get('X-Response-Time') // 获取 时间差
    console.log(`${ctx.method} ${ctx.url} - ${rt}`)
})

// x-response-time
app.use(async (ctx, next) => {
    const start = Date.now()
    await next() // 执行下一个中间件
    const ms = Date.now() - start // 计算时间差,例如 80
    ctx.set('X-Response-Time', `${ms}ms`) // 记录/设置 时间差
})

// response
app.use(async (ctx, next) => {
    ctx.body = 'Hello world'
})

app.listen(3000)
console.log('koa2 已经开始监听 3000 端口')

洋葱圈模型和中间件模型的关系
1.中间件机制:业务模块的划分
2.洋葱圈模型:中间件的执行机制
3.两者要分开来看,不要混在一起

MongoDB数据库

启动 mongodb

在 C:\MongoDB\bin 进入cmd 执行 mongod.exe --dbpath C:\MongoDB\data\db (27017是默认的端口)

测试

在 C:\MongoDB\bin 进入cmd 执行 mongo.exe --port 27017 (27017是默认的端口)
image.png

使用compass

启动之后,点击这里:


image.png

image.png

创建集合:


image.png

插入数据:


image.png

命令行:
查看数据库:show dbs
进入\创建数据库:use comment
查看集合:show collection
插入数据:db.user.insert({username:"wangwu"})
查询:find()


image.png

mongodb:

1、数据库 database
◆mongodb 可以成为数据库系统(服务)
◆一个数据库系统,允许对接很多服务
◆每个数据库,就对接一个数据库

2、集合collection
◆数据库是一个服务(业务)的数据容器
◆一个服务(业务)的数据,要分类管理
◆如留言板系统,有留言数据,有用户数据

3、文档document
◆集合collection也是一个数据容器
◆文档document是单条数据,如一条留言, -一个用户
◆可以被增删改查

4、bson
◆JSON是一种常用的数据格式
◆JSON 是字符串类型的
◆BSON = Binary JSON 即二进制类型的JSON

5、NoSQL
◆关系型数据库(如MySQL)需要学习SQL语言
◆如select content, creator from comments;
◆NoSQL 数据库则无需用SQL语句查询,易学易用

mongodb连接node.js:

1、新建项目,添加nodemon插件
2、安装mongodb插件 cnpm i mongodb --save


image.png

增删改查示例代码:

 // 查询数据
    userCollection.find().sort({ _id: -1 }).toArray((err, result) => {
    userCollection.find().toArray((err, result) => {
        if (err) {
            console.error('查询数据出错', err)
            return
        }
        console.log('查询结果', result)
    })
    // 新增数据
    userCollection.insertOne({
        username: 'shuangyue',
        password: 'abc',
        age: 30,
        city: 'beijing'
    }, (err, result) => {
        if (err) {
            console.error('插入数据出错', err)
            return
        }
        console.log('插入后的返回结果', result.insertedCount, result.insertedId)
    })

    // // 修改数据
    userCollection.updateOne(
        { username: 'zhangsan' }, // 修改的条件
        { $set: { age: 21 , city: 'beijing'} }, // 修改的内容
        (err, result) => {
            if (err) {
                console.error('修改数据出错', err)
                return
            }
            console.log('修改后的返回结果', result.modifiedCount)
        }
    )

    // 删除数据
    userCollection.deleteOne({ username: 'wangwu' }, (err, result) => {
        if (err) {
            console.error('删除数据出错', err)
            return
        }
        console.log('删除成功')
    })

mongoose

1、安装mongoose插件:cnpm i mongoose --save
2、在项目文件夹中新建db文件夹,再在db文件夹中新建db.js,来连接数据库。代码示例:

// 连接数据库(mongodb 的服务端)
const mongoose = require('mongoose')

const url = 'mongodb://localhost:27017'
// 新建一个
const dbName = 'comment2'

mongoose.set('useCreateIndex', true)
mongoose.set('useFindAndModify', true)

// 开始连接
mongoose.connect(`${url}/${dbName}`, {
    useNewUrlParser: true,
    useUnifiedTopology: true
})

const conn = mongoose.connection

conn.on('error', err => {
    console.error('mongoose 连接出错', err)
})

module.exports = mongoose

启动:


image.png

定义Schema 示例代码

// 数据模型(规范数据格式)

const mongoose = require('./db')

// 定义 User Schema (数据规范)
const UserSchema = mongoose.Schema({
    username: {
        type: String,
        required: true, // 必需
        unique: true // 唯一,不重复
    },
    password: String,
    age: Number,
    city: String,
    // 性别
    gender: {
        type: Number,
        default: 0 // 0 - 保密,1 男,2 女
    }
}, {
    timestamps: true // 时间戳,自动添加文档的创建时间、更新时间
})

// 定义 User Model
const User = mongoose.model('user', UserSchema)

// 定义 Comment Schema
const CommentSchema = mongoose.Schema({
    content: {
        type: String,
        required: true // 必需
    },
    username: String // 用户名
}, { timestamps: true })

// 定义 Comment Model
const Comment = mongoose.model('comment', CommentSchema)

module.exports = {
    User,
    Comment
}

操作数据

1、新增数据:

(1)
const zhangsan = new User({
        username: 'zhangsan',
        password: 'abc',
        age: 20,
        city: 'beijing',
        gender: 1
    })
    zhangsan.save()
(2)
    const lisi = await User.create({
        username: 'lisi',
        password: '123',
        age: 23,
        city: 'shanghai'
    })
    console.log('lisi 创建完成', lisi)

2、查询 find方法:

查询列表数据,返回的是数组
const userList = await User.find({ username: 'zhangsan' })
const userList = await User.find().sort({ _id: -1 })
查询单条数据,返回的对象
const user = await User.findOne({ username: 'zhang' })

3、更新:

  const updateResult = await User.findOneAndUpdate(
        { username: 'zhangsan' }, // 条件
        { age: 30 }, // 更新的内容
        {
            new: true // 返回更新后的数据
        }
    )

4、删除remove方法:

 const removeResult = await User.remove({ username: 'lisi' })

登录实现方案与实践

cookie的一二事:
image.png
koa2中的cookie
image.png
session 和 cookie 的关系:
image.png
引入session

1、命令行:cnpm install koa-generic-session --save
2、在app.js


image.png
image.png

3、秘钥:


image.png

留言板项目

初始化开发环境。

1、初始化koa项目;
(1)在父级目录下载koa插件:cnpm install -g koa-generator
(2)生成koa2的目录环境 :koa2 xxx(文件夹名字)
(3)下载依赖包: cnpm install
(4)启动:cnpm run dev
(5)访问localhost:3000

2、规范目录和层级
1、把下图的四个文件夹拖入新建的src文件中


image.png

2、修改配置:bin->www


image.png

3、链接数据库

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。