黑马程序员Node.js全套入门教程的学习笔记
前言
各位读者好,我正在努力学习前端中,这里是我的学习笔记分享,希望能够对大家有用。
我学习的视频链接是 黑马程序员Node.js。
此外,我还有其它前端内容的笔记,大家有需要的可以自行查找。
文章目录
- 前言
- 认识Node.js内置模块
- 认识node.js
- Node.js的运行环境
- node.js的作用
- 常见的终端操作命令
- fs文件系统模块
- .readFile()读取文件
- .wirteFile()写入文件
- 整理成绩案例
- path路径模块
- path.join()拼接路径
- path.basename()解析文件名
- path.extname()获取扩展名
- http模块
- 服务器的基础概念
- 基本服务器创建
- req请求对象
- res响应服务对象
- 解决中文乱码的问题
- 根据不同的url响应不同的html内容
- 模块化
- 模块化的基本概念
- Node.js中模块的分类
- 加载模块
- 模块作用域
- 向外共享模块作用域中的成员
- module对象
- module.exports对象
- CommonJS规定
- npm与包(第三方模块)的搜索与下载
- 注意
- 包管理配置文件
- 解决下包速度慢的问题
- 包的分类
- 规范的包结构
- 实战——开发包
- 需要实现的功能
- 初始化包的结构
- 代码
- npm发布
- 模块的加载机制
- 优先从模块中缓存
- 内置模块的加载机制
- 自定义模块的加载机制
- 第三方模块的加载机制
- 目录作为模块加载机制
- express的使用
- 什么是Express
- Express的安装
- 基本使用
- 创建基本的Web服务器
- 监听GET请求
- 监听POST请求
- 把内容响应给客户端
- 获取URL中携带的参数
- 获取URL中的动态参数
- 托管静态资源
- nodemon的安装并使用
- Express路由
- 路由的匹配过程
- 路由的挂载使用
- 模块化路由
- 为路由模块添加前缀
- Express中间件
- next函数的作用
- 全局生效的中间件
- 局部生效的中间件
- 中间件的使用注意事项
- 中间件的分类
- 使用Express写接口
- 跨域
- CORS响应头部
- 简单请求和预检请求
- 简单请求
- 预检请求
- JSONP接口
- MySQL与MySQL Workbench
- MySQL
- MySQL Workbench操作
- 创建数据库与数据表
- 数据类型
- 写入数据
- SQL语法
- 排序
- count(*)与as函数
- 在项目中操控MySQL模块
- 查询与插入
- 更新与删除
- 实战——Web前后端身份验证
- web开发模式
- 服务端渲染
- 前后端分离
- 身份认证
- Session认证机制
- Cookie
- 在Express中使用Session认证
- JWT认证机制
- 在Express中使用JWT
- 实战代码
认识Node.js内置模块
认识node.js
Node.js是一个基于Chrome V8引擎的JavaScript运行环境。
Node.js的运行环境
node.js的作用
常见的终端操作命令
fs文件系统模块
.readFile()读取文件
/* fs.readFile()的语法格式*/
fs.readFilde(path[.options],callback)
/*
调用fs.readFile()
参数1:读取文件存放的路径
参数2:读取文件时采用的编码格式
参数3:回调函数,拿到失败和成功的结果
*/
/*以utf8的编码格式,读取文件的内容,并打印err和dataStr的值*/
const fs = require('fs')
fs.readFile('./files/11.txt','utf8', fuction(err, dataStr){
/*读取成功,err为null*/
/*读取失败,err为 错误对象 , dataStr 为 undefined*/
/*打印读取失败的结果*/
console.log(err)
console.log('-------')
/*打印读取成功的结果*/
console.log(dataStr)
})
.wirteFile()写入文件
/*语法格式*/
fs.writeFile(file, data[.options], callback)
/*
参数1:必选,写入文件的存放路径
参数2:必选,写入的内容
参数3:可选,编码格式,如utf8
参数4:必选,文件写入后的回调函数
*/
const fs = require('fs')
fs.writeFile('./files/2.txt','abcd',fuction(err){
/*读取成功,err为null*/
/*读取失败,err为 错误对象*/
console.log(err)
})
整理成绩案例
const fs = require('fs')
fs.readFile('./成绩.txt','utf8',function(err,dataStr){
if(err)
return console.log('读取失败'+ err.message)
// console.log('读取文件成功!'+dataStr)
const arrOld = dataStr.split(' ')
const arrNew = []
arrOld.forEach(item => {
arrNew.push(item.replace('=', ': '))
})
console.log(arrNew)
const newStr = arrNew.join('\r\n')
console.log(newStr)
fs.writeFile('./成绩-ok.txt',newStr,function(err){
if(err){
return console.log('写入文件失败!' + err.message)
}
console.log('成绩写入成功')
})
})
path路径模块
path.join()拼接路径
/*导入path模块*/
const path = require('path')
/*注意../会抵消前面的路径*/
const pathStr = path.join('/a', '/b/c', '../', './d', 'e')
console.log(pathStr)
path.basename()解析文件名
/*导入path模块*/
const path = require('path')
/*定义文件的存放路径*/
const fpath = '/a/b/c/index.html'
const fullName = path.basename(fpath)
/*打印出文件名index.html*/
console.log(fullName)
const nameWithoutExit = path.basename(fpath, '.html')
/*打印出index,移除了.html*/
console.log(nameWithoutExit)
path.extname()获取扩展名
/*导入path模块*/
const path = require('path')
/*定义文件的存放路径*/
const fpath = '/a/b/c/index.html'
const fext =path.extname(fpath)
/*打印出.html, 即为文件的扩展名*/
console.log(fext)
http模块
服务器的基础概念
相关概念
基本服务器创建
分四步如下
导入http模块
const http = require('http')
创建web服务器实例
const server = http.creatServer()
为服务器实例绑定request事件,监听客户的请求
server.on('request', function(req,res){
console.log('Someone visit our web serevr')
})
启动服务器
server.listen(80, function(){
console.log('server running at http://127.0.0.1:8080')
})
req请求对象
res响应服务对象
解决中文乱码的问题
根据不同的url响应不同的html内容
const http = require('http')
const server = http.creatServer()
server.on('request', (req, res)=>{
/*获取请求的URL地址*/
const url = req.url
/*设置默认的响应内容404 Not found*/
let content = '404 Not found!'
/*判断用户请求的是否为/或/index.html首页*/
/*判断用户请求的是否为/about.html关于页面*/
if(url === '/' || url === '/index.html'){
content = '<h1>首页</h1>'
}else if(url === '/about.html'){
content = '<h1>关于首页</h1>'
}
/*设置Content-Type响应头,防止中文乱码*/
res.setHeader('Content-Type', 'text/html: charset = utf-8')
/*使用res.end()把内容响应给客户端*/
res.end(content)
})
server.listen(80,()=>{
console.log('server running at http://127.0.0.1')
})
模块化
模块化的基本概念
编程领域中的模块化,就是遵守固定的规则,把一个大文件拆成独立并互相依赖的多个小模块。
把代码进行模块化拆分的好处:
- 提高了代码的复用性
- 提高了代码的可维护性
- 可以实现按需加载
Node.js中模块的分类
Node.js 中根据模块来源的不同,将模块分为了3大类,分别是:
- 内置模块(内置模块是由Node.js 官方提供的,例如fs、path、http等)
- 自定义模块(用户创建的每个.js文件,都是自定义模块)
- 第三方模块(由第三方开发出来的模块,并非官方提供的内置模块,也不是用户创建的自定义模块,使用前需要先下载)
加载模块
模块作用域
好处是防止全局变量的污染。
向外共享模块作用域中的成员
module对象
module.exports对象
在自定义模块中,可以使用module.exports对象,将模块内的成员共享出去,供外界使用。外界用require()方法导入自定义模块时,得到的就是module.exports所指向的对象。
/*
在外界使用require导入一个自定义模块的时候,得到的成员,就是那个模块中,通过module.exports指向的那个对象
*/
const m = require('./自定义模块.js')
console.log(m)
自定义模块
/*在一个自定义模块中,默认情况下,module.exports = {}*/
//对module.exports挂上username属性
module.exports.username = 'zs'
//挂上sayHello的方法
module.exports.sayHello = function(){
console.log('Hello')
}
注意:
- 使用require()方法导入模块时,导入的结果,永远以module.exports指向的对象为准。
- module.exports.age = 12 和 module.exports ={ age = 21}中后者输出
- 由于module.exports 单词写起来比较复杂,为了简化向外共享成员的代码,Node 提供了exports 对象。默认情况下,exports和module.exports 指向同一个对象。最终共享的结果,还是以 module.exports 指向的对象为准。
CommonJS规定
npm与包(第三方模块)的搜索与下载
Node.js中的第三方模块有叫做包。包由第三方团队或个人开发的免费的方便我们写代码的工具。
国外有一家IT公司,叫做npm, Inc.这家公司旗下有一个非常著名的网站: https://www.npmjs.com/,它是全球最大的包共享平台,你可以从这个网站上搜索到任何你需要的包,只要你有足够的耐心!
npm, Inc.公司提供了一个地址为 https://registry.npmjs.org/的服务器,来对外共享所有的包,我们可以从这个服务器上下载自己所需要的包。该公司也提供包的管理工具帮助我们的使用,这个工具不需要额外的下载,在我们下载node.js时就已经有了
格式化时间(不适用包的版本)
temp.js
function dateFormat(dtStr){
const dt = new Date(dtStr)
const y = dt.getFullYear()
const m = padZero(dt.getMonth()+1)
const d = padZero(dt.getDay())
const hh = padZero(dt.getHours())
const mm = padZero(dt.getMinutes())
const ss = padZero(dt.getSeconds())
y.innerHTML=y;
m.innerHTML=m;
d.innerHTML=d;
hh.innerHTML=hh;
mm.innerHTML=mm;
ss.innerHTML=ss;
return y+'-'+m+'-'+d+' '+hh+':'+mm+":"+ss
}
//定义补0的操作
function padZero(n){
return n>9 ? n: '0'+n
}
module.exports = {
dateFormat
}
temp1.js
//导入自定义的格式化时间模块
const TIME = require('./temp.js')
//请调用方法,进行时间的格式化
const dt = new Date()
const newDT=TIME.dateFormat(dt)
console.log(newDT)
使用包的版本
const moment = require('moment')
const dt = moment().format('YYYY-MM-DD HH:mm:ss')
console.log(dt)
注意
可以在npm的第一个链接中找到包的使用说明书
包管理配置文件
解决下包速度慢的问题
下载时,如果出现如下问题
可以复制这段代码解决
npm config set strict-ssl false
npm config set registry http://registry.npm.taobao.org
npm run serve
安装遇到问题可以看这里
包的分类
规范的包结构
实战——开发包
需要实现的功能
- 格式化日期
- 转义HTML中的特殊字符
- 还原HTML中的特殊字符
初始化包的结构
代码
链接:https://pan.baidu.com/s/1GkVCnCiv31U56D2JTAUCqg
提取码:h77j
npm发布
- 在npm的官网上注册账号
- npm账号注册完成后,可以在终端中执行npm login命令,依次输入用户名、密码、邮箱后,即可登录成功。
- 将终端切换到包的根目录之后,运行npm publish命令,即可将包发布到npm上(注意:包名不能雷同)
- 运行npm unpublish 包名 --force命令,即可从npm删除已发布的包。注意,这个命令只能删除72小时以内发布的包。同时,删除的包在24小时内不容许重复发布。
模块的加载机制
优先从模块中缓存
内置模块的加载机制
自定义模块的加载机制
第三方模块的加载机制
目录作为模块加载机制
express的使用
这里是 express中文使用说明书
在使用学习时可以参考一下。
什么是Express
Express的安装
基本使用
创建基本的Web服务器
监听GET请求
监听POST请求
把内容响应给客户端
获取URL中携带的参数
获取URL中的动态参数
托管静态资源
nodemon的安装并使用
Express路由
路由即为映射关系。举例如下
路由的匹配过程
路由的挂载使用
模块化路由
//1.导入路由模块
const router = require('./router.js')
//2.使用app.use()注册路由模块
app.use(router)
/*注意:app.use()函数的作用,就是用来注册全局中间件*/
为路由模块添加前缀
Express中间件
中间件(Middleware ) ,特指业务流程的中间处理环节。
多个中间件之间,共享同一份req和res。基于这样的特性,我们可以在上游的中间件中,统一为req或res 对象添加自定义的属性或方法,供下游的中间件或路由进行使用。
next函数的作用
next函数是实现多个中间件连续调用的关键,它表示把流转关系转交给下一个中间件或路由。
全局生效的中间件
局部生效的中间件
中间件的使用注意事项
中间件的分类
-
应用级别的中间件
-
路由级别的中间件
-
错误级别的中间件
-
Express内置的中间件
- 第三方的中间件
- 自定义中间件
//导入express模块
const express = require('express')
//创建express的服务器实例
const app = express()
//导入自定义的中间件模块
const customBodyParser = require('./custom-body-parser')
//将定义的中间件函数,注册为全局可用的中间件模块
app.use(customBodyParser)
app.post('/user',( req,res)=>{
res.send(req.body)
})
//调用app.listen方法,指定端口号并启动web服务器
app.listen(80,function(){
console.log('express server running at http://127.0.0.1:80')
})
中间件模块
//导入Node.js内置的querystring模块
const qs = require('querystring')
const bodyParser =(req, res, next)=>{
// this.res=res
//定义中间件的业务逻辑
//1.定义str字符串,用于存储客户端发送过来的请求数据
let str = ''
//2.监听req的data事件
req.on('data',(chunk)=>{
str += chunk
})
//3.监听req的end事件
req.on('end',()=>{
//str中存储了完整的请求数据
console.log(str)
//TODO:把字符串格式的请求体数据解析成对象格式
const body = qs.parse(str)
req.body = body
next()
})
}
module.exports = bodyParser
使用Express写接口
使用Express写接口
//导入express模块
const express = require('express')
//创建express的服务器实例
const app = express()
//write your code here
//配置表单解析的中间件
app.use(express.urlencoded({extended:false}))
//一定要在路由之前配置跨域cors这个中间件,从而解决接口跨域的问题
const cors = require('cors')
app.use(cors())
//导入路由模块
const router =require('./apiRouter')
//把路由模块注册到app上
app.use('/api',router)
//调用app.listen方法,指定端口号并启动web服务器
app.listen(80,function(){
console.log('express server running at http://127.0.0.1:80')
})
apiRouter.json
const express = require('express')
const router = express.Router()
//在这里挂载路由
router.get('/get',(req, res)=>{
//通过req.query获取客户端通过查询字符串,发送到服务器的数据
const query = req.query
//使用res.send()方法,向客户端响应处理的结果
res.send({
status:0, //0为处理成功,1为处理失败
msg:'GET 请求成功!', //状态描述
data:query //需要响应给客户端的数据
})
})
router.post('/post', (req, res)=>{
//通过req.body获取请求体中包含的url-encoded的格式数据
const body = req.body
//调用res.send()方法,向客户端响应结束
res.send({
status:0, //0为处理成功,1为处理失败
msg:'POST 请求成功!', //状态描述
data:query //需要响应给客户端的数据
})
})
module.exports = router
跨域
CORS响应头部
简单请求和预检请求
简单请求
预检请求
JSONP接口
MySQL与MySQL Workbench
MySQL
这里推荐大家我之前学习的一篇文章,这个文章内容是我在同类文章中个人认为是比较易读全面的。
MySQL学习文章
MySQL Workbench操作
MySQL Workbench 是MySQL可视化操作软件
下载官网,全部next就行
创建数据库与数据表
创建数据表
数据类型
设计表的字段
写入数据
SQL语法
SELECT
注意:多个列名称可以用英文逗号隔开
INSERT INTO
UPDATA
注意:多个列名称修改可以用英文逗号隔开
DELETE
WHERE子语句
AND关系
OR关系
排序
多重排序
count(*)与as函数
在项目中操控MySQL模块
- 安装操作MySQL数据库的第三方模块(mysql)
- 通过 mysql模块连接到MySQL 数据库
- 通过mysql模块执行SQL语句
查询与插入
更新与删除
实战——Web前后端身份验证
web开发模式
服务端渲染
前后端分离
身份认证
Session认证机制
Cookie
在Express中使用Session认证
JWT认证机制
JWT(英文全称:JSON Web Token)是目前最流行的跨域认证解决方案。
在Express中使用JWT
注意:只要配置成功了express-jwt 这个中间件,就可以把解析出来的用户信息,挂载到req.user属性上
实战代码
基于 项目开发文档的API的开发
这里面是关于登录验证,上传文章的API项目
链接:https://pan.baidu.com/s/1Dbbs2Qat5zj8xtCY0v3zbg
提取码:qid3
声哥codeGrandMaster: jar -jar springboot_01_quickstart-0.0.1-SNAPSHOT.jar 拼写错误,应为 java -jar springboot_01_quickstart-0.0.1-SNAPSHOT.jar